C# Coding Style Guidelines

Key: A good variable name describes the semantics not the type.

– Prefix private member variables with m_.
  public class SomeClass
  {
     private int m_Number;
  }
– With generics, use capital letters for types. Reserve suffixing Type when disabling with the .NET type type.
  // Correct
  public class LinkedList<K, T> { … }
  // Avoid:
  public class LinkedList<KeyType, DataType> { … }
– Use delegate inference instead of explicit delegate instantiation.
  delegate void SomeDelegate();
  public void SomeMethod() { … }
  SomeDelegate someDelegate = SomeMethod;
– With anonymous methods mimic the code layout of a regular method, aligned with the anonymous delegate declaration.
  a) Comply with placing an open curly brace in a new line.
  delegate void SomeDelegate(string someString);
  // Correct:
  public void InvokeMethod()
  {
     SomeDelegate someDelegate = delegate(string name)
                                                    {
                                                        MessageBox.Show(name);
                                                     }

     someDelegate("Juval");
  }
– With empty parenthesis on parameterless anonymous methods.
  a) Omit the parenthesis only if the anonymous method could have been used on any delegate.
  delegate void SomeDelegate();
  // Correct:
  SomeDelegate someDelegate = delegate()
                                                 {
                                                     MessageBox.Show("Hello");
                                                  }

  // Avoid:
  SomeDelegate someDelegate = delegate
                                                 {
                                                     MessageBox.Show("Hello");
                                                  }

– Avoid methods with more than 5 arguments. Use structures for passing multiple arguments.
– Never hardcode a numeric value, always declare a constant instead.
– Use the const directive only on natural constants such as the number of days of week.
Avoid using const on read-only fields. For that, use the readonly directive.
– In a catch statement that throws an exception, always throw the original exception to maintain the stack location of the original error.
When defining custom exceptions, derive the custom exception from ApplicationException and provide custom serialization.
– Avoid friends assemblies, as it increases inter-assembly coupling.
– Assert every assumption, on average, every fifth line is an assertion.
Always explicitly initialize an array of reference types using a for loop.
  MyClass[] array = new MyClass[100];
  for (int index = 0; index <= array.Length; index++)
  {
     array[index] = new MyClass();
  }
Avoid using the new inheritance qualifier. Use override instead.
Always mark public and protected methods as virtual in a non-sealed class.
Avoid explicit casting. Use the as operator to defensively cast to a type.
– With delegates as class members
  a) Copy a delegate to a local variable before publishing to avoid concurrency race condition.
  b) Always check a delegate for null before invoking it.
  public class MySource
  {
     public event EventHandler MyEvent;
     public void FireEvent();
     {
        EventHandler temp = MyEvent;
        if (temp != null)
        {
           temp(this, EventArgs.Empty);
        }
     }
  }
– Do no provide public event member variables. Use event accessors instead.
  public class MySource
  {
     MyDelegate m_SomeEvent;
     public event MyDelegate SomeEvent;
     {
        add
        {
           m_SomeEvent += value;
        }
        remove
        {
           m_SomeEvent -= value;
        }
     }
  }
Use the EventsHelper class defined in Programming .NET Components to publish events defensively.
– Never assume a type supports an interface. Defensively query for that interface.
  SomeType obj1;
  IMyInterface obj2;
  /* Some code to initialize obj1, then: */
  obj2 = obj1 as IMyInterface;
  if (obj2 != null)
  {
     obj2.Method();
  }
  else
  {
     // Handle error in expected interface
  }
– Avoid providing methods on structures.
  a) Parameterized constructors are encouraged.
  b) Can overload operators.
– Do not use late-binding invocation when early-binding is possible.
– Never use goto unless in a switch statement fall-through.
– Always have a default case in a switch statement that asserts.
  int number = SomeMethod();
  switch(number)
  {
     case 1:
        Trace.WriteLine("Case 1:");
        break;
     case 2:
        Trace.WriteLine("Case 2:");
        break;
     dfault:
        Debug.Assert(false);
        break;
  }
– Do not use the this reference unless invoking another constructor from within a constructor.
  // Example of proper use of ‘this’
  public class MyClass
  {
     public MyClass(string message) { }
     public MyClass() : this ("hello") { }
  }
– Do not use the base reference to access base class members unless you wish to resolve a conflict with a subclass 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) {}
     virtual public void Bark(int howLong) {}
  }
  public class GermanShepherd : Dog
  {
     public GermanShepherd(string name) : base(name) {}
     override public void Bark(int howLong) { base.Bark(howLong); }
  }
– Implement Dispose() and Finalize() methods based on the template in …
– Avoid casting to and from System.Object in code that uses generics. Use constraints or the as operator instead:
  // Avoid:
  class MyClass<T>
  {
     void SomeMethod(T t)
     {
        object temp = t;
        SomeClass obj = (SomeClass)temp;
     }
  }
  // Correct:
  class MyClass<T> where T : SomeClass
  {
     void SomeMethod(T t)
     {
        SomeClass obj = t;
     }
  }
– Do not define constraints in generic interfaces. Interface level-constraint can be often be replaced by strong-typing.
  public interface IList<T> where T : Customer { …  }
  public interface ICustomerList : IList<Customer> { … }
– Do not define method-specific containts in interfaces.
– Always prefer using C# generics in data structures.

– Try to initialize local variables as soon as they are declared. For example:
    string name = myObject.Name;
or
    int val = time.Hours;
– If you initialize a dialog try to use the using statement:
  using (OpenFileDialog openFileDialog = new OpenFileDialog()) {
     …
  }
Note on using Statement: The object you instantiate must implement the System.IDisposable interface.
– A return statement should not use outer most parentheses, e.g., return (n * (n+1) + 2);
– Generally use brackets even if there is only one statement in a loop.
– A logical block of lines should be formatted as a table:
   string name    = "Mr. Ed";
   int    myValue = 5;
   Test   aTest    = Test.TestYou;
– Only use all upper case for identifiers if it consists of an abbreviation which is one or two identifiers of three or more characters should use Pascal Casing instead. For Example:
   public class Math
   {
       public const PI = …
       public const Rfc = …
       public const feigenBaumNumber = …
   }

Advertisements

Leave a Reply

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