C# coding standards

While reading some blogs today, I ran across a nice C# coding standards document.  The document closely follows Microsoft's “Design Guidelines for Class Library Developers” and is very similar to my personal standards.  My notes, as well as some additional standards I try to follow, are below:

3.2.2
I prefer to prefix private fields with an underscore.

5.2.6
Not necessary.  The runtime knows when objects are no longer used, even within the body of a method.  For example:

1 MyObject o = new MyObject();
2 o.DoSomething();
3 DoSomethingElse();

If a GC occurs at line three, the object referenced by "o" may be garbage collected. 

7.2.1
Classes with internal accessibility don't need to follow this, as versioning is not an issue.  All consumers of objects of that type are compiled with the class.

10.2.6
StringBuilder is not a panacea.  See http://weblogs.asp.net/ricom/posts/43628.aspx and http://weblogs.asp.net/ricom/posts/40778.aspx for appropriate usage.

11.2.2
I prefer to have all of the fields at the top of a class in order of accessibility from public to private.

Personal:
- For methods that return arrays, always return an array.  If the method produces no results, return an empty array instead of null.  If you must return null, note this in the XML documentation.

- Use explicit interface implementation for code that does not adhere to the roll of the object, ie. debug code.  For example, sometimes it's helpful while debugging to get a certain value from each object in a custom collection.  A GetProductIDs method can be written to obtain these values, but the method has no practical use to the consumer and, since it's debug code, it may be changed or removed in the future.  It also pollutes the public interface.  Classes that contain methods like these should implement an IDebug interface and implement those members with explicit interface implementation.

- Provide as much information as possible in exceptions, including how to possibly avoid the exception in the future.  Provide state information, if possible.  For example, if a ProcessInvoice method encounters a line item without an ID, include the name of the product in the error message or in a property off of the custom exception.  This can make debugging much easier for the consumer.

- Never store the integral value of an enum between application sessions.  Members of the enum may be removed or reordered.

8 Comments

  • Thanks, Doug. I couldn't remember where I'd read/heard that (PDC?) and couldn't confirm.

  • Good document, although I can't stand the one about using spaces instead of tabs! Configuring VS.NET to use tabs means everyone can make the indents "appear" to be 2 or 3 or 4 spaces, thus allowing room for personal preference, without messing up file diffs in VSS. Using spaces on the other hand, if people use different values (and they always want to) means that diffs are impossible for all practical purposes!

  • I second what Paul said! Also note that Visual Studio can take spaces and turn them into tabs and vice versa (Edit-Advanced-Tabify/Untabify) or even format code your way, with curly braces on a new line or trailing the IF statement. That will work, but it will still hose up your file diffs.

  • Another reason to nullify local variables could be preventing misuse of outdated information. For example, if some method call invalidates local variable value (e.g cached data), it makes sense to set it to null.

  • 3.2.2: For public fields and constants, I use Pascal not camel - in part so that if a public field or constant later gets converted to a property, public interface stays the same. But I also recognize that 7.2.1 is a good idea (don't have public fields in the first place). 10.2.4 shows public constants in Pascal case...



    3.2.2 I also use the leading _ for member variables that JK and sourceforge projects including NAnt use.



    4.2.5: I find the <list> tag useful for documenting preconditions and postconditions within the <remarks> block, with a <para> header saying "Preconditions" or "Postconditions". Note that NDoc does support <list>. This complements in-code assertion checking described in 7.2.7, 7.2.8.



    5.2.2: I avoid the ? : operator because it's too cryptic, agreeing with the SourceForge NAnt coding standard, except in member-field initialization expressions.



    5.2.6: I agree with JK that this is not necessary for GC, but do sometimes do this in the Ilya scenario.



    8.2.7: I always try to throw custom exceptions only out of public interfaces, derived from ApplicationException, which may include inner .NET exceptions. I also use an enum "Code" field sometimes within an exception type such as "CustomComponentException", rather than typing every exception.



    8.2.10: My understanding is that ApplicationException is intended for use as a base for all app custom exception, differentiated from Exception which is the base for all that come out of the framework. The MS Exception Block included exception derives from ApplicationException, I believe for this reason.



  • dude get a life .. progtam in java

  • I've just started at a place where the coding standards mandate the use of m_ for member variables, p_ for parameters and prefixes for types, such as 'str' for strings.

    So, you might have something like this in the body of a method:

    m_strName = p_strName;

    Horrible. Really horrible.

  • LOL! The whole reason for the standard is to avoid personal preferences. So whey you say "I prefer an underscore on private variables", nobody is going to ask you to articulate what possible benefit that has (millions of developers prefer to use this.field to distinguish local variables from class variables, for example). Having dozens of standards makes a mockery of the term "standard".

    I will say, however, that the utterly ridiculous pattern of slapping a type prefix on a variable (which came from the lack of type safety in Visual Basic) was pushed by Microsoft for eons, so they are not generally to be trusted.

Comments have been disabled for this content.