Tuesday, June 5, 2012

Good coding practices and guidelines, C#

While working on fixing FxCop errors I came across good code practices and guidelines, some of which I know earlier but would like to sum up here:

1. Do not declare visible instance fields
The primary use of a field should be as an implementation detail. Fields should be private or internal and should be exposed by using properties. Accessing a property is as easy as accessing a field and the code in a property's accessors can change as the type's features expand without introducing breaking changes. Properties that just return the value of a private or internal field are optimized to perform on par with accessing a field; there is very little performance gain associated with using externally visible fields over properties.Externally visible refers to public, protected, and protected internal accessibility levels.

2. Mark members as static
Members that do not access instance data or call instance methods can be marked as static. After you mark the methods as static, the compiler will emit non-virtual call sites to these members. Emitting non-virtual call sites will prevent a check at runtime for each call that ensures that the current object pointer is non-null. This can result in a measurable performance gain for performance-sensitive code. In some cases, the failure to access the current object instance represents a correctness issue

3. Do not decrease inherited member visibility 
You should not change the access modifier for inherited members. Changing an inherited member to private does not prevent callers from accessing the base class implementation of the method. If the member is made private and the type is unsealed, inheriting types can call the last public implementation of the method in the inheritance hierarchy. If you must change the access modifier, either the method should be marked final or its type should be sealed to prevent the method from being overridden.

4. Do not expose generic lists
System.Collections.Generic.List<T> is a generic collection designed for performance not inheritance. System.Collections.Generic.List<T> does not contain virtual members that make it easier to implement new behaviors. The following generic collections are designed for inheritance and should be exposed instead of System.Collections.Generic.List<T>.
  1. System.Collections.ObjectModel.Collection<T>
  2. System.Collections.ObjectModel.ReadOnlyCollection<T>
  3. System.Collections.ObjectModel.KeyedCollection<TKey, TItem>

To fix a violation of this rule, change the System.Collections.Generic.List<T> type to one of the generic collections designed for inheritance.

5. Do not ignore method results
Issues: Either one of following comes under this issue category
1. A new object is created but never used.
2. A method that creates and returns a new string is called and the new string is never used.
3. A COM or P/Invoke method that returns an HRESULT or error code that is never used.

Why these are considered as issues: It makes you aware of circumstances such as:
1. Unnecessary object creation and the associated garbage collection of the unused object degrade performance.
2. Strings are immutable. Methods such as ToUpper return a new instance of a string instead of modifying the instance of the string in the calling method.
3. Ignoring an HRESULT or error code can lead to unexpected behavior in error conditions or to low-resource conditions.

How to fix: (Fixes mentioned in order to issue description)
1. If method A creates a new instance of B object that is never used, pass the instance as an argument to another method or assign the instance to a variable. If the object creation is unnecessary, remove it.
2. Method A calls method B but does not use the new string instance that method B returns. Pass the instance as an argument to another method, assign the instance to a variable, or remove the call if it is unnecessary.
3. Method A calls method B but does not use the HRESULT or error code that the method returns. Use the result in a conditional statement, assign the result to a variable, or pass it as an argument to another method.


No comments:

Post a Comment