Sie sind auf Seite 1von 14

Iowa Department of Natural Resources Information Technology Bureau

C# Coding Guidelines for .NET


(Use guidelines for VB Coding in .NET)

Document Version 1.0 August 2006

Revision History
Version 1.00 Date 08/21/2006 Comment Created.

IowaDNR C# Guidelines.doc

2 of 14

TABLE OF CONTENTS

Introduction ....................................................................................................4 1.1. Scope .....................................................................................................4 1.2. Terminology & Definitions.......................................................................4 2. Naming Conventions .....................................................................................5 2.1. General Guidelines .................................................................................5 2.2. Name Usage...........................................................................................6 3. Coding Style ..................................................................................................8 3.1. Formatting ..............................................................................................8 3.2. Code Commenting..................................................................................8 4. Language Usage ...........................................................................................9 4.1. General...................................................................................................9 4.2. Variables & Types ................................................................................10 4.3. Flow Control .........................................................................................10 4.4. Exception Handling...............................................................................11 4.5. Events, Delegates, & Threading ...........................................................12 4.6. Object Composition ..............................................................................12 5. Object Model Design ...................................................................................12

1.

IowaDNR C# Guidelines.doc

3 of 14

1. Introduction
This document describes recommended guidelines for developing applications using C# Language. These guidelines should be used for VB in the .NET framework although the syntax is written in C#. The goal is to define guidelines to enforce consistent style and help internal and external developers avoid common mistakes. In addition, these guidelines will be required by all vendors that develop applications for the Department. This document covers Naming Conventions, Coding Style, Language Usage, and Object Model Design

1.1. Scope
This document applies to C# Language and the .NET Framework.

1.2. Terminology & Definitions


Camel Case A word with the first letter lowercase, and the first letter of each subsequent wordpart capitalized. Example: facilityName Pascal Case A word with the first letter capitalized, and the first letter of each subsequent word-part capitalized. Example: FacilityName

IowaDNR C# Guidelines.doc

4 of 14

2. Naming Conventions
The following naming conventions apply to naming projects, source files, and identifiers including Fields, Variables, Properties, Methods, Parameters, Classes, Interfaces, and Namespaces.

2.1. General Guidelines


1. 2. 3. 4. 5. 6. Always use Camel Case or Pascal Case names. Avoid ALL CAPS and all lowercase names. Do not create namespaces, classes, methods, properties, fields, or parameters that vary only by capitalization. Do not use names that begin with a numeric character. Do not use single character variables names, except in For loops. Do not use Hungarian Notation Examples: strAddress iCount

7.

Always choose meaningful and specific names. Always err on the side of verbosity. 8. Avoid using abbreviations unless the full name is excessive (over 20 characters). 9. Avoid abbreviations longer than 5 characters. 10. Variables and Properties should describe an entity not the type or size. 11. Do not use C# reserved words as names. 12. Avoid adding redundant or meaningless prefixes and suffixes to identifiers. Example: public enum ColorsEnum{} public class CAffiliate {} public struct EnvelopeStruct {} 13. Do not include the parent class name within a property name. Example: Affiliate.Name NOT Affiliate.AffiliateName 14. Try to prefix Boolean variables and properties with Can, Is, or Has. 15. Append computational qualifiers to variable names like Average, Count, Sum, Min, and Max where appropriate. Example: private double averageWellDepth 16. When defining a root namespace, use a Product, Company, or Developer Name as the root. Example: IowaDNR.StringUtilities

IowaDNR C# Guidelines.doc

5 of 14

2.2. Name Usage


Identifier Project File Naming Convention Pascal Case. Always match Assembly Name & Root Namespace. Example: IowaDNR.Web.csproj -> IowaDNR.Web.dll -> namespace IowaDNR.Web Pascal Case. Always match Class name and file name. Avoid including more than one Class, Enum(global), or Delegate(global) per file. Use a descriptive file name when containing multiple Class, Enum, or Delegates. Example: MyClass.cs => public class MyClass {} Try to use Pascal Case. Use a name describing the file contents. Pascal Case. Try to partially match Project/Assembly Name. Example: namespace IowaDNR.Web {} Pascal Case. Use a noun or noun phrase for class name. Add an appropriate class-suffix when sub-classing another type. Examples: private class MyClass {} internal class SpecialAttribute : Attribute {} public class CustomCollection : CollectionBase {} private struct ApplicationSettings {} Pascal Case. Always prefix interface name with capital I. Example: interface IFacility Always use a single capital letter, such as T or K. Example: public class FifoStack<T> { public void Push(<T> obj) {}

Source File

Resource Or Embedded File Namespace

Class or Struct

Interface

Generic Class & Generic Parameter Type

IowaDNR C# Guidelines.doc

6 of 14

public <T> Pop() {} Method } Pascal Case. Use a Verb or Verb-Object Pair. Example: public void Execute() {} private string GetFacilityName(Facility target) {} Pascal Case. Property name should represent the entity it returns. Never prefix property names with Get or Set. Example: public string Name { get{} set{} } Pascal Case. Avoid using non-private Fields; use Properties instead. Example: public string Name; protected IList InnerList; Camel Case and prefix with a single underscore (_) character. Example: private string _name; Apply the same guidelines as for Fields. Choose appropriate Field access-modifier above. Pascal Case (both the Type and the Options) Add the FlagsAttribute to bit-mask multiple options. Example: public enum WaterbodyTypes { Lake, Pond, River, Stream } Apply the same guidelines as for Fields. Choose appropriate Field access-modifier above. Example: public event EventHandler LoadGrid; Camel Case. Avoid using single characters like x or y except in For loops. Avoid enumerating variable names like text1, text2, text3, etc. Camel Case. Example: public void Execute(string commandText, int iterations) {}

Property

Field (Public, Protected, or Internal)

Field (Private)

Constant or Static Field Enum

Delegate or Event

Variable (inline)

Parameter

IowaDNR C# Guidelines.doc

7 of 14

3. Coding Style
Each developer has a preference to coding style. However, consistent layout, format, and organization are recommended for creating maintainable code. The following section describes the preferred way to implement consistent, readable C# source code. The bottom line is to write clean, readable code in such a way that it needs minimal comments to understand.

3.1. Formatting
1. 2. 3. 4. 5. 6. Never declare more than 1 namespace per file. Avoid putting multiple classes in a single file. Always put curly braces ({ and }) on a new line. Declare each variable independently not in the same statement. Place namespace using statements together at the top of the file. Group internal class implementation together by type. Examples: a. Member variables. b. Constructors & Finalizers. c. Nested Enums, Structs, and Classes. d. Properties. e. Methods. 7. The order listed above is the preference. 8. Segregate interface Implementation by using the #region statements. 9. Indent all code blocks contained within braces. 10. Use white space (CR/LF, Tabs, etc) liberally to separate and organize code. 11. Avoid declaring multiple attribute declarations within a single line. Instead stack each attribute as a separate declaration. Example: // Bad! [Attribute1, Attribute2, Attribute3] Public class MyClass {} // Good! [Attribute1] [Attribute 2] [Attribute 3] Public class MyClass {}

3.2. Code Commenting


1. 2. Use // or /// but never /* */ Do not flowerbox comment blocks. Example: // ********************************** // Comments block

IowaDNR C# Guidelines.doc

8 of 14

// ********************************** 3. 4. 5. 6. Use inline-comments to explain assumptions, known issues, and algorithm insights. Do not use inline-comments to explain obvious code. Well written code is self documenting. Only insert inline-comments for Bad Code to say fix this code otherwise, rewrite it. Do not write comments for every line of code or variable declared variable and method names should be meaningful enough and not require minimal comments. Include Task-List keywords flags to enable comment-filtering. Example: // TODO: Place Database Code Here // UNDONE: Removed P\Invoke call due to errors // HACK: Temporary fix until able to refactor

7.

8.

Always apply C# comment-blocks (///) to public, protected, and internal declarations. 9. Only use C# comment-blocks for documenting the API. 10. Always include <summary> comments. Include <param>, <return>, and <exception> comment sections where applicable. 11. Include <see cref= /> and <seeAlso cref= /> where possible. 12. Always add CDATA tags to comments containing code and other embedded markup in order to avoid encoding issues. Example: /// <example> /// Add the following key to the appSettings section of your config: /// <code><! [CDATA[ /// <configuration> /// <appSettings> /// <add key=mySetting value=myValue /> /// </appSettings> /// </configuration> /// ]]></code> /// </example>

4. Language Usage
4.1. General
1. Explicitly declare all identifiers with the appropriate access modifier. Example: // Bad! void WriteEvent(string message) // Good! private void WriteEvent(string message)

IowaDNR C# Guidelines.doc

9 of 14

4.2. Variables & Types


1. 2. 3. Try to initialize variables where you declare them. Use the simplest data type, list, or object required. For example, use int over long unless you know you need to store 64 bit values. Always use the built-in C# data type aliases, not the .NET common type system (CTS). Example: short NOT System.Int16 int NOT System.Int32 long NOT System.Int64 string NOT System.String 4. 5. 6. 7. 8. Only declare member variables as private. Use properties to provide access to them with public, protected, or internal access modifiers. Avoid using inline numeric literals. Instead use a constant or enum. Avoid using string literals. Instead use constants, resources, registry, or other data sources. Only declare constants for simple types. Declare readonly or static readonly variables instead of constants for complex types. Avoid direct casts. Instead, use the as operator and check for null. Example: object dataObject = LoadData(); DataSet dsTanks = dataObject as DataSet; If(dsTanks != null) {} 9. Always prefer C# Generic collection types over standard or strong-typed collections. (.NET Framework 2.0 or higher) 10. Avoid boxing and unboxing value types. Example: int count = 1; object refCount = count; int newCount = (int)refCount; 11. 12. 13. 14.

// Implicitly boxed. // Explicitly unboxed.

Try to use the @ prefix for string literals instead of escaped strings. Prefer String.Format() or StringBuilder over string concatenation. Avoid concatenating a string inside a loop. Do not compare strings to String.Empty or to check for empty strings. Instead, compare by using String.Length == 0. 15. Avoid hidden string allocations within a loop. Use String.Compare() instead.

4.3. Flow Control


1. 2. Avoid creating recursive methods. Use loops or nested loops instead. Avoid evaluating Boolean conditions against true or false. Example:

IowaDNR C# Guidelines.doc

10 of 14

// Bad! if (isValid == true) {} // Good! if (isValid) {}

3. 4.

5. 6.

Avoid assignment within conditional statements. Example: if((i=2)==2) {} Use the ternary conditional operator only for trivial conditions. Avoid complex or compound ternary operations. Example: int result = isValid ? 9 : 4; Avoid compound conditional expressions use Boolean variables to split parts into multiple manageable expressions. Prefer nested if/else over switch/case for short conditional sequences and complex conditions.

4.4. Exception Handling


1. 2. 3. 4. 5. 6. Do not use try/catch blocks for flow control. Only catch exceptions that you can handle. Never declare an empty catch block. Avoid nesting a try/catch within a catch block. Order exception filters from most to least derived exception type. Avoid re-throwing exceptions. Instead, allow the exception to bubbleup. If re-throwing an exception, omit the exception argument from the throw statement so the original call stack is preserved. Example: // Bad catch(Exception ex) { Log(ex); throw ex; } // Good Catch(Exception ex) { Log(ex); throw; } 7. Only use the finally block to release resources from a try statement. 8. Always use validation to avoid exceptions. Example: // Bad try {

IowaDNR C# Guidelines.doc

11 of 14

sqlConn.Close(); } catch(Exception ex) { // handle exception if already closed! } // Good If(sqlConn.State != ConnectionState.Closed) { sqlConn.Close(); } 9. Avoid defining custom exception classes. Use existing exception classes instead. If you have to write a custom exception then always derive from 10. When throwing a new Exception, always pass the innerException in order to maintain the exception tree & inner call stack. 11. There is no need to catch the general exception in all your methods. Leave it open and let the application crash. This will help you find most of the errors during development cycle. 12. Do not write try-catch in all of your methods. Use it only if there is a possibility that a specific exception may occur. For example, if you are writing to a file, handle only FileIOException.

4.5. Events, Delegates, & Threading


1. 2. 3. Always check Event & Delegate instances for null before invoking. Always derive a custom EventArgs class to provide additional data. Use the default EventHandler and EventArgs for most simple events.

4.6. Object Composition


1. 2. 3. Avoid declaring methods with more than 7 parameters. Refactor or consider passing a struct or class instead. Consider using method overloading instead of the params attribute. Wrap instantiation of IDisposible objects with a using statement to ensure that Dispose() is automatically called. Example: using(SqlConnection cnSql = new SqlConnection(_connectionString)) {}

5. Object Model Design


1. 2. 3. 4. Always prefer delegation over inheritance. Do the simplest thing that works, then refactor as time permits. Always separate presentation layer from business logic. Always prefer interfaces over abstract classes.

IowaDNR C# Guidelines.doc

12 of 14

IowaDNR C# Guidelines.doc

13 of 14

IowaDNR C# Guidelines.doc

14 of 14

Das könnte Ihnen auch gefallen