This is something I'm doing for my team at work...thought you may like a look / comment etc...
Know the SOLID principles...
See http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod (the first 5). These are fundamental principles for good OO software design, know them...love them!
If you don't need it...delete it!
As for Code Comments below, never check in an Excluded Class to the source control system. It adds noise and is a great way to have hard to trace exceptions if they're accidentally re-included.
I know it's in the policy document but to be honest no-one uses generated docs when tests are a better alternative for learning code.
Code comments should only be used to clarify complex algorithms, apart from that they just add cruft to code and make it harder to read. Method / parameter names should be descriptive (I frankly don't care how long they are, that's what intellisense is for!). If you can't work out what a method does from its name...rename it. Or if a method does more stuff than you can reasonably fit in a name, you need to refactor the method.
Keep classes compact
No hard and fast rule here but if you're >200 lines in a single class think seriously whether you need to refactor. If you follow rule 1 of SOLID (Single Responsibility Principle) then this should rarely happen.
Keep names meaningful
There are, no prizes for being terse...the more readable your code, the easier it is for you and others to find bugs.
Use 'var' instead of the type name where appropriate.
In general it's both neater and increases code readability to replace an often lengthy type name with the 'var' keyword. The main counterpoint to this is when the return type of an operation is not obvious from the name of the method / context.
StringBuilder sb = new StringBuilder(256);
UTF8Encoding e = new UTF8Encoding();
MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
We'd end up with this
var sb = new StringBuilder(256);
var e = new UTF8Encoding();
var md5 = new MD5CryptoServiceProvider();
Use the 'as' operator when casting reference types
The 'as' operator avoids runtime exceptions (e.g., (string)foo["bar"] could well throw an exception), in addition it is far more performant that doing an 'is' followed by an explcit cast.
Prefer enums over bools when they are used as return types from methods.
Enumerators make your code more readable (e.g. returning the value Car.Red from is CarColor rather returning true from the method IsCarRed) , they also make it far easier to extend code later on (true and false being rather limiting...)
Exceptions should only be used to indicate Technical Errors
Exceptions in .NET are valuable and when used well are a great feature. However, they should never be used as a tool in normal programmatic flow, only when an object does not perform an operation according to its specification / interface should an exception be returned.
Never catch an exception you can't do something with
Unless you actually do something with an exception, let it bubble up to somewhere which can do something (even if just reporting it to the user)
Use nullable types sparingly
Nullable types encourage optional parameters...optional parameters encourage branching within methods and reduce testability. Avoid them.
Never call the GC manually
It's smarter than you (oh, EXCEPT if you're using unmanaged objects)
Always use generic collection types over their non-generic ancestors
The generic collections are faster, avoid boxing and are basically cooler
The same applies to the new Concurrent collections when multithreading in 4.
Use the TPL
In .NET 4 when using concurrency prefer the new TPL http://msdn.microsoft.com/en-us/library/dd460717.aspx functions over managing threads 'by hand'
Prefer simplicity over more complex language features
Keeping your code simple to follow is critical to making changes easy and relatively low risk, one of the simplest ways to achieve this is to keep your code as transparent and simple to follow as you can.
Write, Test, Refactor, Test
Well factored code is easier to read, easier to change and easier to debug...A great test for well factored code is the 'Single Responsibility Principal', each method should really only perform a single operation on an object (for example, a single method should never both update and delete, or compress and save to disk).
Â· Avoid branching within methods
Â· Where you can avoid recursive methods
If you can't navigate through a single class file without collapsing sections of the code then your class is almost certainly in need of refactoring.
Regions add noise and make it harder to read code.
Only place they can be valuable is with long test classes...
They mostly avoid concurrency issues at the expense of performance...there's almost always a better way.
Use Conditional Statements and Conditional Directives
When used properly, Conditional Debug Statements and conditional directives such as those below can be extremely useful in adding extra information to help you debug apps:
The main advantage of this method of adding additional debug information is that they are not output when the code is compiled in release mode.
If you DO use nullable types NEVER cast directly to the non nullable form
Again, this is a potential source of runtime exceptions. Instead, always use the .GetValueOrDefault() method and test for the default value (if necessary) before trying to use the value.
Avoid using the 'this.' Keyword
If your naming scheme is correct, you should never have to use 'this.' to specify that an object is local to your class.