.Net Coding Standards Part2 : Coding Practices


This post is in continuation to my previous post “.Net Coding Standards Part1 : Naming conventions and style”. If you wish to go through it again, you can access it here.

Here i will be taking you through some Coding practices in DotNet coding. I would request you to go through them slowly and with no rush. It is essential you keep note of these practices before you start coding.

1.    Avoid putting multiple classes in a single file.

2.    A single file should contribute types to only a single namespace. Avoid having multiple namespaces in the same file.

3.    Avoid files with more than 500 lines (excluding machine-generated code).

4.    Avoid methods with more than 200 lines.

5.    Avoid methods with more than 5 arguments. Use structures for passing multiple arguments.

6.    Lines should not exceed 120 characters.

7.    Do not manually edit any machine-generated code.

  • a.    If modifying machine generated code, modify the format and style to match this coding standard.
  • b.    Use partial classes whenever possible to factor out the maintained portions.

8.    Avoid comments that explain the obvious. Code should be self-explanatory. Good code with readable variable and method names should not require comments.

9.    Document only operational assumptions, algorithm insights and so on.

10.    Document the code with C# documentation comments.

11.    With the exception of zero and one, never hard-code a numeric value. Always declare a constant instead.

12.    Use the const directive only on natural constants such as the number of days of the week.

13.    Avoid using const on read-only variables. For that, use the readonly directive.

public class ReadOnlyVariables
{
public const int DaysInWeek = 7;

public readonly int Number;

public ReadOnlyVariables(int someValue)
{
Number = someValue;
}
}

14.    Catch only exceptions for which you have explicit handling.

15.    In a catch statement that throws an exception, always throw the original exception (or another exception constructed from the original exception) to maintain the stack location of the original error.

catch (OverflowException exception)
{
// Some handling.
throw;
}

16.    Avoid error codes as method return values.

17.    Avoid defining custom exception classes.

18.    When defining custom exceptions:

  • a.    Derive the custom exception from Exception. It was originally thought that custom exceptions should derive from ApplicationException. However in practice this has not been found to add significant value.
  • b.    Provide custom serialization.

19.    Do not put multiple Main() methods in a single assembly.

20.    Make only the most necessary types public. Mark others as internal.

21.    Do not write code that relies on an assembly running from a particular location.

22.    Minimize code in application assemblies (.exe client assemblies). Use class libraries instead to contain business logic.

23.    Avoid providing explicit values for enums unless they are integer powers of 2 and the enumeration is marked with the FlagsAttribute.

// Correct.
public enum CorrectColor
{
Red,
Green,
Blue
}

// Avoid.
public enum AvoidColor
{
None = 0,
Red = 1,
Green = 2,
Blue = 3
}

24.    Avoid specifying a type for an enum.

// Avoid.
public enum AvoidColorType : long
{
Red,
Green,
Blue
}

25.    Always use a curly brace scope in an if, while, do, for, foreach, lock and using statement, even if it contains a single statement.

26.    Avoid using the ternary conditional operator (?:).

27.    Avoid function calls in Boolean conditional statements. Assign into local variables and check on them.

public void AvoidThisMethod()
{
// Avoid.
if (IsEverythingOk())
{
}
}

public void UseThisMethod()
{
bool ok;

// Correct.
ok = IsEverythingOk();
if (ok)
{
}
}

28.    Always use zero-based arrays.

29.    With indexed collections, use zero-based indexes.

30.    Always explicitly initialize an array of reference types using a for loop.

31.    Do not provide public or protected member variables. Use properties instead.

32.    Avoid using the new inheritance qualifier. Use override instead.

33.    Never use unsafe code, except when using interop.

34.    Avoid explicit casting. Use the as operator to defensively cast to a type.

Dog dog;
GermanShepherd shepherd;

dog = new GermanShepherd(“Rin-Tin-Tin”);
shepherd = dog as GermanShepherd;
if (shepherd != null)
{
}

35.    Always check a delegate for null before invoking it.

36.    Avoid defining event-handling delegates. Use EventHandler<TEventArgs>.

37.    Avoid raising events explicitly. Use a protected virtual method to raise events. The name of the protected virtual method should be the same as the event name prefixed with On.

public event EventHandler Click;

private void SomeMethod()
{
OnClick(EventArgs.Empty);
}

protected virtual void OnClick(EventArgs e)
{
if (Click != null)
{
Click(this, e);
}
}

38.    Never hardcode strings that will be presented to end users. Use resources instead.

39.    Never hardcode strings that might change based on deployment such as connection strings.

40.    Use string.Empty instead of “”.

41.    When building a long string, use StringBuilder, not string.

42.    Avoid providing methods on structures.

  • a.    Parameterized constructors are encouraged.
  • b.    Can overload operators.

43.    Never use goto unless in a switch statement fall-through (goto case, goto default).

44.    Always have a default case in a switch statement. Throw an Exception when the default signals an error condition.

public void SampleSwitch()
{
int number;

number = SampleMethod();
switch (number)
{
case 1:
Trace.WriteLine(“Case 1”);
break;

case 2:
Trace.WriteLine(“Case 2”);
break;

default:
throw new FatalException(
Properties.Resources.SampleSwitchUnknownNumber + number);
}
}

45.    Do not use the this reference unless invoking another constructor from within a constructor.

46.    Do not use the base word to access base class members unless you wish to resolve a conflict with a subclasses member of the same name or when invoking a base class constructor.

// Example of proper use of ‘base’.
public class Dog
{
public Dog(string name)
{
}

public virtual void Bark(int seconds)
{
}
}

public class GermanShepherd : Dog
{
public GermanShepherd(string name)
: base(name)
{
}

public override void Bark(int seconds)
{
base.Bark(seconds);
}
}

47.    Implement Dispose() and Finalize() methods based on the template in the .NET Framework Developers Guide: Implementing a Dispose Method
http://msdn2.microsoft.com/en-us/library/fs2xkftw.aspx

48.    Always run code unchecked by default (for the sake of performance), but explicitly in checked mode for overflow- or underflow-prone operations.

49.    Avoid explicit code exclusion of method calls (#if … #endif). Use conditional methods instead.

[Conditional(“SampleCondition”)]
public void SampleMethod()
{
}

50.    Do not cast to and from System.Object in code that uses generics. Use constraints or the as operator instead.

public class SampleClass
{

}
// Correct.
public class CorrectClass<T> where T : SampleClass
{
void SampleMethod(T t)
{
SampleClass sample;

sample = t;
}
}

// Avoid.
public class AvoidClass<T>
{
void SampleMethod(T t)
{
object temp;
SampleClass sample;

temp = t;
sample = (SampleClass)temp;
}
}

51.    Do not define constraints in generic interfaces. Interface-level constraints can often be replaced by strong-typing.

public class Customer
{
}

// Correct.
public interface ICustomerList : IList<Customer>
{
}

// Avoid.
public interface IList<T> where T : Customer
{
}

52.    Do not define method-specific constraints in interfaces.

53.    Do not define constraints in delegates.

54.    If a class or a method offers both generic and non generic flavors, always prefer using the generics flavor.

55.    When implementing a generic interface that derives from an equivalent non-generic interface (such as IEnumerable<T>), use explicit interface implementation on all methods, and implement the non-generic methods by delegating to the generic ones.

public sealed class MyCollection<T> : IEnumerable<T>
{
private List<T> _store;

IEnumerator<T> IEnumerable<T>.GetEnumerator()
{
return _store.GetEnumerator();
}

IEnumerator IEnumerable.GetEnumerator()
{
IEnumerable<T> enumerable = this;
return enumerable.GetEnumerator();
}
}

Hope these two posts were useful to you. These were like DotNet Coding guide for me always. Hoping it to be the same for you. Enjoy Reading.

Feel free to leave a reply here...

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s