1) Using the wrong type of collection
.Net has a lot of collection classes and they are all specialized on specific tasks. Make sure to select the right one with care. Making the wrong choice can make your code inefficient
, have unexpected consequences as well as making your code's intent unclear.
Read more here: https://msdn.microsoft.com/en-us/library/6tc79sx1%28v=vs.110%29.aspx
2) Not using yield return
When enumerating over objects for
another caller you should use yield return instead of creating a return
collection. Some benefits of this pattern are that:
* You don't have to keep the whole collection in memory
(it might be pretty big)
* Yield return immediately returns control to the caller after each iteration
* You only process results that actually are used (why iterate the whole collection if the caller just wants the first item?)
3) Parsing ambiguous dates
Be sure to specify a format
provider when you parse ambiguous dates. For example, it is not clear
what part of the date string "03/04/05" that are the month, day, and
year and it can lead to serious errors
for a user. Use DateTime.ParseExact / DateTimeOffset.ParseExact to provide the specific format:
var date = DateTime.ParseExact("01/12/2000", "MM/dd/yyyy", null)
4) Rethrowing Exceptions with an exception instance
If you want to catch and rethrow an exception, be sure to use the simple throw;
syntax. If you use throw ex;
it will not preserve the exception call stack.
5) Accessing virtual members in a constructor
The virtual keyword allows members of a class to be overridden in a derived class. Constructors are run from the base class to the most derived class. So if you call an overridden method from the constructor of a base class you may be executing code that is not ready for execution
(it might depend on initialization done in it's own constructor).
public class Parent
public virtual void Method()
public class Child : Parent
public override void Method()
Instantiating the Child class will print the following:
I.e. Child method is called before Child constructor.
6) Exceptions in static constructors
If a class throws an exception in a static constructor, it renders the class useless
. Even a non-static construction will not be possible. The class will keep throwing a System.TypeInitializationException whenever it is referenced (static or not).
7) Optional parameters in external assemblies
Optional parameters may not work like expected when referenced from external assemblies. Let's say that you provide some functionality packed in a DLL. Now let's say that you want to make a minor change in your code (changing an optional parameter to another value). The consumer of the DLL must recompile their application
in order for your change to take effect.
Read more here: http://www.blackwasp.co.uk/DefaultParameterProblem.aspx
8) Generic methods with a non-generic overload
Let's say you have a generic method that takes a parameter of type T and another method with the same name but with a parameter of a specific type. The compiler will select the most specific method
for each parameter type, and the specified type is more specific than the generic one.
Let's say you have the following class:
public void Test<T>(T parameter)
public void Test(string parameter)
The following code...
var instance = new GenericTest();
Will print the following result:
I.e. the compiler selected the more specific string method for the second call.
9) Changing the hash code after adding an object to a dictionary
Dictionaries depends on the keys' return value of Object.GetHashCode(). This means that the hash code of a key must not be changed
after it has been added to the dictionary.
10) ValueType.Equals will be slow if the struct contains reference members
Be sure to not have any reference-members in your struct if you want to use the ValueType.Equals-method to compare two instances. This is due to the fact that ValueType.Equals will resort to Reflection
to determine the equality of the reference members and this might be a bit slower than expected.