Skip to content

Latest commit

 

History

History
465 lines (363 loc) · 10.1 KB

File metadata and controls

465 lines (363 loc) · 10.1 KB

##Naming Convetions and Style

  1. Use Pascal casing for type and method names
public class SomeClass
{
	const int DefaultSize = 100;
	public void SomeMethod()
	{
	}
}
  1. Use camel casing for local variable names and method arguments
void SomeMethod(int someNumber)
{
	int number;
}
  1. Prefix interface names with I
interface IMyInterface
{
}
  1. Avoid using Hungarian notation

  2. Use this if you want to distinguish member variables with local

  3. Suffix custom attribute classes with Attribute

  4. Suffix custom exception classes with Exception

  5. Name methods using verb-object-pair, such as ShowDialog()

  6. Methods with return values should have a name describing the value returned, such as GetObjectState()

  7. Use descriptive variable names a) Avoid single character variable names, such as i or t. Use index or temp instead b) Do not abbreviate words (such as num instead of number)

  8. Always use C# predefined types rather than the aliases in the System namespace when declaring local variable, class field or method argument. But use types from System namespace when using static members

	// Avoid
	Object myObject;
	String myString;
	Int32 myNumber;
	string.Empty
	int.MaxValue
	string.IsNullOrEmpty()
	
	// Correct
	object myObject;
	string myString;
	int myNumber;
	String.Empty
	Int32.MaxValue
	String.IsNullOrEmpty()	
  1. With generics, use capital letters for types. Reserve suffixing Type when dealing with the .Net type Type
	// Avoid
	public class LinkedList<KeyType,DataType>
	{
	}
	
	// Correct
	public class LinkedList<K, T>
	{
	}
  1. Use meaningful namespaces such as the product name or the company name

  2. Avoid fully qualified type names. Use the using statement

  3. Avoid putting a using statement inside a namespace

  4. Group all framework namespaces together and put custom or third-party namespaces underneath

	// Avoid
	using MyCompany;
	using MyControls;
	using System;
	using System.Collections.Generic;
	using System.ComponentModel;
	using System.Data;
	
	// Correct
	using System;
	using System.Collections.Generic;
	using System.ComponentModel;
	using System.Data;
  1. Use delegate inference instead of explicit delegate instantiation
	public delegate void ImageChangedDelegate();
	public void ChangeImage()
	{
	}
	
	// Avoid
	ImageChangedDelegate imageChanged = new ImageChangedDelegate(ChangeImage);
	
	// Correct
	ImageChangedDelegate imageChanged = ChangeImage;
  1. Indent comments at the same level of indentation as the code you are documenting

  2. All comments should pass spell checking. Misspelled comments indicate sloppy development.

  3. All member variables should be declared at the top, with one line separating them from the properties or methods

public class MyClass
{
	int number;
	string name;
	
	public void SomeMethod1()
	{
	}
	
	public void SomeMethod2()
	{
	}
}
  1. Declare a local variable as close as possible to its first use.

  2. A file name should reflect the class it contains.

  3. When using partial types and allocating a part per file, name each file after the logical part that part plays

// In MyClass.cs
public partial class MyClass
{
}

// In MyClass.Designer.cs
public partial class MyClass
{
}
  1. Always place an open curly brace { in a new line.

  2. With anonymous methods, mimic the code layout of a regular method, aligned with the delegate declaration. (complies with placing an open curly brace in a new line)

delegate void SomeDelegate(string someString);

// Avoid
void InvokeMethod()
{
	SomeDelegate someDelegate = delegate(string message) {MessageBox.Show(message);};
	someDelegate("Hello");
}

// Correct
void InvokeMethod()
{
	SomeDelegate someDelegate = delegate(string message)
								{
									MessageBox.Show(message);
								};
	someDelegate("Hello");
}
  1. Use empty parantheses on parameter-less anonymous methods.Omit the parentheses only if the anonymous method could have been used on any delegate;
delegate void SomeDelegate();

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

// Correct
SomeDelegate someDelegate = delegate()
							{
								MessageBox.Show("Hello");
							}
  1. With Lambda expressions, mimic the code layout of a regular method, aligned with the delegate declaration. Omit the variable type and rely on type inference, yet use parentheses:
delegate void SomeDelegate(string someString);

// Avoid
SomeDelegate someDelegate = (string message) =>
							{
								Trace.WriteLine(message);
								MessageBox.Show(message);
							};
// Correct
SomeDelegate someDelegate = (message) =>
							{
								Trace.WriteLine(message);
								MessageBox.Show(message);
							};
  1. Only use in-line Lambda expressions when they contain a single simple statement. Avoid multiple statements that require a curly brace or a return statement with in-line expressions. Omit parentheses:
delegate void SomeDelegate(string someString);

void MyMethod(SomeDelegate someDelegate)
{
}

// Avoid
MyMethod((message) => {Trace.WriteLine(message);MessageBox.Show(message);});

// Correct
MyMethod(message => MessageBox.Show(message));

Coding Practices

  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 50 lines

  5. Avoid methods with more than 5 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

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

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

  10. Avoid method-level documentation. Use method-level comments only as a tool tips for other developers.

  11. In general, prefer overloading to default parameters:

// Avoid
class MyClass
{
	void SomeMethod(int number = 123)
	{
	}
}

// Correct
class MyClass
{
	void SomeMethod()
	{
		SomeMethod(123);
	}
	
	void SomeMethod(int number)
	{
	}
}
  1. When using default parameters, restrict them to natural immutable constants such as null, false, or 0:
void SomeMethod(int number = 0)
{
}
	
void SomeMethod(string message = null)
{
}
	
void SomeMethod(bool flag = false)
{
}
  1. Assert every assumption. On average, every 6th line is an assertion
using System.Diagnostics;

object GetObject()
{
}

object someObject = GetObject();
Debug.Assert(someObject != null);
  1. Every line of code should be walked through in a "white box" testing manner

  2. Catch only exceptions for which you have explicit handling

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

catch(Exception ex)
{
	MessageBox.Show(ex.Message);
	throw;
}
  1. Avoid error codes as method return values

  2. Avoid defining custom exception classes

  3. When defining custom exception: a) Derive the custom exception from Exception b) Provide custom serialization

  4. Avoid multiple Main() methods in a single assembly

  5. Make only the most necessary types public, mark others as internal

  6. Avoid code that relies on an assembly running from a particular location

  7. Minimize code in application assemblies(EXE client assemblies). Use class libraries instead to contain business logical

  8. Avoid providing explicit values for enums unless they are integer powers of 2:

// Avoid
public enum Color
{
	Red = 1,
	Green = 2,
	Blue = 3
}

// Correct
public enum Color
{
	Red,
	Green,
	Blue
}
  1. Avoid specifying a type for an enum
// Avoid
public enum Color : long
{
	Red,
	Green,
	Blue
}
  1. Always use a curly brace scope in an if statement, even if it conditions a single statement

  2. Avoid using the ternary conditional operator

  3. Always use zero-based arrays

  4. With indexed collection, use zero-based indexes

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

public class MyClass
{
}

const int ArraySize = 100;

MyClass[] someArray = new MyClass[ArraySize];

for(int index = 0; index < someArray.Length; index++)
{
	array[index] = new MyClass();
}
  1. Do not provide public or protected member variables. Use properties instead

  2. Avoid explicit properties that do nothing except access a member variable. Use automatic properties instead:

// Avoid
class MyClass
{
	int number;
	public int Number
	{
		get
		{
			return number;
		}
		set
		{
			number = value;
		}
	}
}

// Correct
class MyClass
{
	public int Number { get; set; }
}
  1. Avoid using the new inheritance qualifier. Use override instead

  2. When override Equals, override GetHashCode too

  3. Never use unsafe code, except when using interop

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

	// Avoid
	Dog dog = new GermanShepherd();
	GermanShepherd shepherd = (GermanShepherd)dog;
	
	// Correct
	Dog dog = new GermanShepherd();
	GermanShepherd shepherd = dog as GermanShepherd;
	if (shepherd != null)
	{
	}
  1. Always check a delegate for null before invoking it

  2. Never hardcode string that will be presented to end users. Use resources instead

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

  4. Use String.Empty instead of ""

// Avoid
string myString = "";

// Correct
string myString = String.Empty;
  1. Never use goto

  2. Always have a default case in a switch statement

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

int CalcPower(int number, int power)
{
	result = 1;
	for(int count = 1; count <= power; count++)
	{
		checked
		{
			result *= number;
		}
	}
	
	return result;
}