C Sharp Coding Guidelines and Best Practices 2
C Sharp Coding Guidelines and Best Practices 2
Page 1
INTRODUCTION ......................................................................................... 4
2.1.2
2.1.3
Uppercase ................................................................................... 4
2.1.4
2.2
Naming rules................................................................................... 5
2.2.1
Namespaces ................................................................................ 6
2.2.2
Classes ....................................................................................... 6
2.2.3
Method ....................................................................................... 7
2.2.4
Interfaces.................................................................................... 7
2.2.5
Enums ........................................................................................ 8
2.2.6
2.2.7
Variables ..................................................................................... 9
2.2.8
Properties .................................................................................. 10
2.2.9
Events ...................................................................................... 11
2.2.10
2.2.11
General ................................................................................. 12
3.2
Ordering ....................................................................................... 15
3.3
Indentation ................................................................................... 15
3.3.1
3.3.2
3.4
Comments .................................................................................... 16
3.4.1
3.4.2
3.4.3
3.5
Formatting .................................................................................... 19
3.6
Declaration ................................................................................... 19
3.6.1
3.6.2
Initialization ............................................................................... 19
3.6.3
3.7
Statements ................................................................................... 20
Page 2
3.7.1
3.7.2
3.7.3
3.7.4
3.7.5
While/do-while Statements........................................................... 22
3.7.6
3.7.7
Performance ................................................................................. 24
4.2
Usage .......................................................................................... 28
4.3
Design ......................................................................................... 32
4.4
Globalization ................................................................................. 37
4.5
Security ....................................................................................... 38
4.6
Interoperability .............................................................................. 42
4.7
Exceptions .................................................................................... 44
REFERENCES: ......................................................................................... 48
APPNEDIX A ............................................................................................... 49
Page 3
1 Introduction
Quality has its own value in a software product development. The simplest method
for guaranteeing that a crew of the developers furnishes high quality deliverables is
to establish a coding standard. A comprehensive coding standard is essential for a
successful product delivery. Its not just the delivery but also the after delivery tasks
like support gets impacted by coding standards followed by the development team.
The standard helps in enforcing best practices and avoiding pitfalls and makes
knowledge dissemination across team easier.
A comprehensive coding standard encompasses all aspects of code construction and,
while developers should exercise prudence in its implementation, it should be closely
followed. Completed source code should reflect a harmonized style, as if a single
developer wrote the code in one session.
2.1.3 Uppercase
All letters in the identifier are capitalized. Use this convention only for identifiers that
consist of two or fewer letters. For example: System.IO, System.Web.UI.
Page 4
Notes/Examples
Class
Pascal Case
Attribute Class
Pascal Case
Exception Class
Pascal Case
Constant
Pascal Case
Enum type
Pascal Case
Enum values
Pascal Case
Event
Pascal Case
Interface
Pascal Case
Local variable
Camel Case
Method
Pascal Case
Namespace
Pascal Case
Property
Pascal Case
Pascal Case
Camel Case
Parameter
Camel Case
Has a prefix of I
Page 5
2.2.1 Namespaces
The general rule for namespace naming is:
[<Company
Name>].[<Product
Name>].[<SubNameSpace>]
Example:
Technology
Name>].[<Feature
Company.ProductName.Ecommerce.DataLayer;
Do avoid the possibility of two published namespaces having the same name.
Do use whole, simple and descriptive words and avoid acronyms and
abbreviations unless abbreviation is much more widely used than long form,
such as URL, Xml etc.
2.2.2 Classes
Do name classes with nouns or noun phrases using Pascal Case. Names may
start with an adjective, but should always end with a descriptive noun or noun
phrase (User, CustomUser or ReadonlyUser).
Do not use plural tense, use a second descriptive noun, or noun phrase
instead (UserCollection instead of Users)
Do not use any prefix (such as C, for example). Where possible, avoid
starting with the letter I, since that is the recommended prefix for interface
names. If you must start with that letter, make sure the second character is
lowercase, as in IdentityStore.
Do use suffixes at times. For example, if your system uses agents then
naming something DownloadAgent conveys real information.
Do not bring the name of the class that the class derives from into the
derived class's name (However there are some special cases mentioned
later). A class should stand on its own. It doesn't matter what it derives from.
Page 6
Example:
public class InvoiceItemGroup { }
public class Invoice { }
2.2.3 Method
Example:
Invoice.ProcessInvoice();
// AVOID! No need to mention Invoice in name
Invoice.Process(); // PREFER
Do Use the verb-noun method for naming routines that perform some
operation on a given object which describes the operation, such as
CalculateInvoiceTotal().
2.2.4 Interfaces
Do prefix interface names with the letter I, to indicate that the type is an
interface.
Do use similar names when defining a class/interface pair where the class is a
standard implementation of the interface. The names should differ only by the
Page 7
interface IComponent { }
class Component : IComponent { }
interface IServiceProvider{ }
interface IFormatable { }
2.2.5 Enums
Do use a plural name for enumerations with bit fields as values also called
flags enumerations.
SearchOptions(bitwise flags)
Do use the Flags custom attribute if the numeric values are meant to be
bitwise OR-ed together
[Flags]
public enum Bindings
{
CreateInstance,
DefaultBinding,
ExcatBinding,
GetField,
GetProperty,
IgnoreCase,
InvokeMethod,
NonPublic,
OABinding,
SetField
Page 8
Do use int as the underlying type of an enum. (An exception to this rule is if
the enum represents flags and there are more than 32 flags, or the enum
may grow to that many flags in the future, or the type needs to be different
from int for backward compatibility.)
Do use enums only if the value can be completely expressed as a set of bit
flags. Do not use enums for open sets (such as operating system version).
2.2.7 Variables
Do use descriptive names such that a variables name that clearly indicates
what the purpose of the variable is and what value it will hold.
Do prefix private fields with an underscore (_) like _privateField. All other
variable must follow simply camel Case.
Do use the this keyword when referring to members at a classs root scope
from within a lower level scope, as in this.name.
Do not reserve parameters for future use. If more data is need in the next
version, a new overload can be added.
Do use computation qualifiers (avg, sum, min, max, index) as prefix and
suffix of a variable name where appropriate.
Do name Collections as the plural form of the singular objects that the
collection contains. A collection of Book objects is named Books.
Do not using terms such as Flag when naming status variables, which differ
from Boolean variables in that they may have more than two possible values.
Instead of orderFlag, use a more descriptive name such as orderStatus.
Page 9
Do use a meaningful name even for a short-lived variable that may appear in
only a few lines of code. Use single-letter variable names, such as i or j for
short-loop indexes only.
Do not use all uppercase with underscores between words for constants, such
as NUM_DAYS_IN_WEEK. Constants follow the same naming rules as
properties. The aforementioned constant would be named NumDaysInWeek.
Example:
public class Person
{
private int _birthYear;
public Person(int birthYear)
{
this._birthYear = birthYear;
}
public int BirthYear
{
get{ return this._birthYear; }
set{ this._birthYear = value; }
}
public string FormatBirthYear(int totalLength)
{
string birthYearText = this._birthYear.ToString();
int yearLength = birthYearText.length;
}
}
2.2.8 Properties
Page 10
Do consider having a property with the same name as a type. When declaring
a property with the same name as a type, also make the type of the property
be that type. In other words, the following is okay
public enum Color {...}
public class Control
{
public Color Color { get {...} set {...} }
}
but this is not
public enum Color {...}
public class Control
{
public int Color { get {...} set {...} }
}
In the latter case, it will not be possible to refer to the members of the Color
enum because Color.Xxx will be interpreted as being a member access that
first gets the value of the Color property (of type int) and then accesses a
member of that value (which would have to be an instance member of
System.Int32).
2.2.9 Events
Do Consider naming events with a verb. Use a gerund (the "ing" form of a
verb) to create an event name that expresses the concept of pre-event, and a
past-tense verb to represent post-event. For example, a Close event that can
be canceled should have a Closing event and a Closed event.
Page 11
2.2.10
Case sensitivity
Dont use names that require case sensitivity. Components might need to be
usable from both case-sensitive and case-insensitive languages. Since caseinsensitive languages cannot distinguish between two names within the same
context that differ only by case, components must avoid this situation.
Examples of what not to do:
Dont have a method with two parameters whose names differ only by case.
void F(string a, string A)
Dont have a namespace with two types whose names differ only by case.
System.WinForms.Point p;
System.WinForms.POINT p;
Dont have a type with two methods whose names differ only by case.
void f();
void F();
2.2.11
General
When using Visual Studio.NET 2003 or Visual Studio.NET 2005 you can
specify code regions. Code regions are basically blocks of code that you can
collapse within the Visual Studio IDE. What code regions enable you to do is
group related pieces of code together which makes things easier to find. For
instance, I typically will group all my properties for a class within a Properties
code region.
#region P R O P E R T I E S
public string MyProp;
#endregion
Page 12
Always use c# predefined types rather than the aliases in the System
namespace. For example
Use object and not Object
Use string and not String
Use int and not Int32
Names with semantic content are preferred to names with type specifications
(sizeOfArray instead of anInteger).
Object references should be in camel case and they should be named after
their class. For example
InvoiceItemGroup invoiceItemGroup = new InvoiceItemGroup()
With the exception of zero and one, never hard code a numeric value; always
declare a constant instead. Please also note it is NOT ok to satisfy this
guideline by defining constants such as FortyTwo = 42.
Avoid using function calls in Boolean conditional statements. Assign into local
variable and check on them
bool ValidateInput()
{
.
Page 13
Do not use letters that can be mistaken for digits, and vice versa. To
create obfuscated code, use very short, meaningless names formed from
the letters O, o, l, I and the digits0 and 1. For example
bool b001 = (lo == l0) ? (I1 == 11) : (lOl != 101);
should not be written
Do not change a loop variable inside a for loop block. Updating the loop
variable within the loop body is generally considered confusing, even more
so if the loop variable is modified in more than one place.
Do not make explicit comparisons to true or false.
It is usually bad style to compare a bool-type expression to true or false.
Example:
while (condition == false) // wrong; bad style
while (condition != true) // also wrong
while (((condition == true) == true) == true) // where do you
stop?
while (booleanCondition) // OK
Page 14
3 Coding Style
3.1 Source Files
Source files should contain one class per source file and name of file
should be same as class name. For example a file containing class Invoice
should have name Invoice.cs.
3.2 Ordering
Group all framework namespaces together and put custom or third party
namespaces underneath.
using System;
using System.Data;
using Company.ProductName.Core;
using Company.ProductName.Data;
3.3 Indentation
3.3.1 Wrapping Lines
When an expression will not fit on a single line, break it up according to these
general principles:
Break after a comma.
Break after an operator.
Prefer higher-level breaks to lower-level breaks.
Align the new line with the beginning of the expression at the same level on
the previous line
A good coding practice is to make the tab and space chars visible in the editor which
is used.
Example
SomeMethod(longExpresssion1, longExpression2,
longExpression3)
Page 15
3.4 Comments
C# programs can have two kinds of comments: implementation comments and
documentation comments. Implementation comments are those found in C++, which
are delimited by /*...*/, and //. Documentation comments are C# only, and are
delimited by special XML tags that can be extracted to external files for use in
system documentation.
Implementation comments are meant for commenting out code or for comments
about the particular implementation. Doc comments are meant to describe the
specification of the code, from an implementation-free perspective, to be read by
developers who might not necessarily have the source code at hand.
Comments should be used to give overviews of code and provide additional
information that is not readily available in the code itself.
Consider an example below.
if ( grandTotal >= 1000.00)
{
grandTotal = grandTotal * 0.90;
}
Looking at the code in example above one can figure out that a 10% discount is
being given on orders of $1,000 dollars or more. Why is this being done? Is there a
business rule that says that large orders get a discount? Is there a limited-time
special on large orders or is it a permanent program? Was the original programmer
just being generous? I do not know unless it is documented somewhere, either in the
source code itself or in an external document
Comments should contain only information that is relevant to reading and
understanding the program.
Following are recommended commenting techniques:
Avoid adding comments at the end of a line of code; end-line comments make
code more difficult to read. However, end-line comments are appropriate when
annotating variable declarations. In this case, align all end-line comments at a
common tab stop.
Comment anything that is not readily obvious in the code. This point leads to
allot of subjective interpretations. Use your best judgment to determine an
appropriate level of what it means for code to be not really obvious.
Block Comments
Page 16
Page 17
{
// Do a triple-flip.
...
}
else
{
return false;
}
If you need to give information about a class, interface, variable, or method that isn't
appropriate for documentation, use an implementation block comment or single-line
comment immediately after the declaration.
Document comments must not be positioned inside a method or constructor
definition block, because C# associates documentation comments with the first
declaration after the comment.
Page 18
3.5 Formatting
Visual studio 2005 has an auto formatting feature and overall we should follow its
style and rules.
3.6 Declaration
3.6.1 Number of Declarations per Line
One declaration per line is recommended since it encourages commenting1. In other
words,
int level;
int size;
Do not put more than one variable or variables of different types on the same line
when declaring them.
3.6.2 Initialization
Try to initialize local variables as soon as they are declared.
string name = myObject.Name;
or
int val = time.Hours;
Note: If you initialize a dialog try to use the using statement:
using (OpenFileDialog openFileDialog = new OpenFileDialog())
{
...
}
No space between a method name and the parenthesis "(" starting its
parameter list.
The opening brace "{" appears in the next line after the declaration
statement.
The closing brace " }" starts a line by itself indented to match its
corresponding opening brace.
Page 19
3.7 Statements
3.7.1 Simple Statements
Each line should contain only one statement.
Page 20
Page 21
Page 22
4 Best Practices
This section discuss about the best practices that should be followed while writing
code in c#. The section is divided in subsection based on Performance, Usage,
Design, Globalization, Security, Interoperability and Exceptions.
Most of the content of this section has been taken as it is from
http://www.codeproject.com and FxCop (http://www.gotdotnet.com/team/fxcop/)
rules.
Page 23
4.1 Performance
}
Prefer StringBuilder instead of string concatenation.
C# string is immutable, i.e., cannot be altered. When you alter a string, you
are actually creating a new string causing the following:
The code uses more memory than necessary.
Creates more work for the garbage collector.
Makes the code execution run slower.
Therefore, you should prefer using StringBuilder (Append method).
Code snippets:
//NO
string strConcat;
ArrayList arrayOfStrings = new ArrayList();
arrayOfStrings.Add("a");
arrayOfStrings.Add("b");
foreach (string s in stringContainer) {
strConcat += s;
}
//YES
StringBuilder sbConcat = new StringBuilder ();
foreach (string s in arrayOfStrings ) {
sbConcat.append(s);
}
For very simple concatenation we should directly add them as
follows:
//Yes
return a + b + c;
//NO
StringBuilder a = new StringBuilder();
Page 24
a.Append(b);
a.Append(c);
return a;
Page 25
Page 26
'foreach' and 'for' statements serve the same goal - run in loop over block of
statements.
The main differences in using the foreach statement are that you do not need to
deal with increments and with the end of the loop expression. Moreover, the
foreach statement is designed to traverse through the entire collection. One can
say that foreach is a private case of for.
In the code snippets below, we can see that both loop blocks produce the same
results, only under the hood the foreach hurts the performance. More variables
are involved and additional heavy array copy.
The foreach is far handier to use especially for collections but if your code runs
over large collections, prefer using 'for'.
Code snippets:
//foreach
int[] arrayOfInts= new int[5];
int sum= 0;
foreach(int i arrayOfInts) {
sum+= i;
}
//for
int[] arrayOfInts= new int[1];
int sum= 0;
for(int i = 0; i < arrayOfInts.Length; i++) {
sum+= arrayOfInts[i];
Page 27
4.2 Usage
Page 28
Code snippets:
//NO
short shortNum;
int i = 32768;
shortNum = (short) i;
// problem after statment excution
// the shortNum variable has an uninitialized value,
//YES
try {
shortNum = checked((short)i); // solution
}
catch(OverflowException efx) {}
Use Explicit interface to 'hide' the implementation of an interface
Implementing an interface explicitly 'hides' the interface methods. Visual Studio
does not display the interface methods in the intellisense.
Code snippets:
//interface definition
public interface IChild{
bool IsHuman();
void lie();
}
//class definition
public Pinocchio: IChild {
IChild.IsHuman() //explicit interface implementation
{
}
public void Lie(); //regular interface implementation
}
//using the object
static void main()
{
// Visual studio will not display
// the isHuman mwthod in the intellisence.
Pinocchio o = new Pinocchio();
((IChild) o).IsHuman(); // using the IsHuman method explicitly.
o.Lie();
}
Collection properties should be read only.
Page 29
Page 30
Code snippets:
//Old way
string sFilePath = c:\\a\\b\\c.txt;
//The C# way
string sFilePath = @c:\a\b\c.txt;
Make your API assembly CLS Compliant.
The CLS-Compliant attribute cause the compiler to check whether your public
exposed types in the assembly are CLS-Compliant.
Prefer to define the attribute for the entire assembly, especially for API. The
incentive to create a CLS compliant assembly is that any assembly written in one
of the .NET aware languages can use your assembly more efficiently because
there is no data type interoperability.
Code snippets:
using System;
[assembly:CLSCompliant(true)]
Page 31
4.3 Design
Page 32
Page 33
= 0,
Error
= 1,
Warning = 2,
Info
= 3,
Verbose = 4
}
//Correct
[Flags]
public enum TraceOptions
{
None
0,
CallStack
= 0x01,
LogicalStack = 0x02,
DateTime
= 0x04,
Timestamp
= 0x08,
}
//Wrong
[Flags]
public enum BadTraceOptions
{
CallStack
0,
LogicalStack = 0x01,
DateTime
= 0x02,
Timestamp
= 0x04,
Page 34
Page 35
set
using
string,
call
SomeUri
new
Page 36
4.4 Globalization
Page 37
}
}
}
4.5 Security
Page 38
Page 39
Virtual methods and their Overrides require the same Link Demand
status.
If a virtual method has a Link Demand, so should any override of it, and if an
Override has a Link Demand, so should the overridden virtual method
Ex: If a method in the base class is declared as virtual, and has the security
status, then immediate overriding of that member should also have the same
security status.
Example:
public interface ITestOverrides
{
[EnvironmentPermissionAttribute(SecurityAction.LinkDemand,
Unrestricted=true)]
Object GetFormat(Type formatType);
}
public class OverridesAndSecurity : ITestOverrides
{
// Rule violation: The interface has security, and this
implementation does not.
object ITestOverrides.GetFormat(Type formatType)
{
return (formatType == typeof(OverridesAndSecurity) ?
this : null);
}
// These two methods are overridden by DerivedClass and
DoublyDerivedClass.
[EnvironmentPermissionAttribute(SecurityAction.LinkDemand,
Unrestricted=true)]
public virtual void DoSomething()
Page 40
Page 41
4.6 Interoperability
[ClassInterface(ClassInterfaceType.None)]
public class ExplicitInterface : IExplicitInterface
{
public void SomeMethod() {}
}
Use StructLayout attribute for classes and structs when using COM
Interop.
The attributes cause the compiler to pack the structure in sequential memory
so that it can be sent to unmanaged code correctly (unmanaged code that
expects a specific layout).
Code snippets:
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Sequential)]
public struct st
{
int i;
float f;
}
Auto layout types should not be ComVisible
Auto layout types are managed by the common language runtime. The layout
of these types can change between versions of the .NET Framework, which
will break COM clients that expect a specific layout. Note that if the
Page 42
Page 43
4.7 Exceptions
A well-designed set of error handling code blocks can make a program more robust
and less prone to crashing because the application handles such errors. The following
list contains suggestions on best practices for handling exceptions:
The method you choose depends on how often you expect the event to occur.
If the event is truly exceptional and is an error (such as an unexpected endof-file), using exception handling is better because less code is executed in
the normal case. If the event happens routinely, using the programmatic
method to check for errors is better. In this case, if an exception occurs, the
exception will take longer to handle.
Use try/finally blocks around code that can potentially generate an exception
and centralize your catch statements in one location. In this way, the try
statement generates the exception, the finally statement closes or deallocates
resources, and the catch statement handles the exception from a central
location.
Always order exceptions in catch blocks from the most specific to the least
specific. This technique handles the specific exception before it is passed to a
more general catch block.
When creating user-defined exceptions, you must ensure that the metadata
for the exceptions is available to code executing remotely, including when
exceptions occur across application domains. For example, suppose
Application Domain A creates Application Domain B, which executes code that
throws an exception. For Application Domain A to properly catch and handle
the exception, it must be able to find the assembly containing the exception
thrown by Application Domain B. If Application Domain B throws an exception
that is contained in an assembly under its application base, but not under
Application Domain A's application base, Application Domain A will not be able
to find the exception and the common language runtime will throw a
FileNotFoundException. To avoid this situation, you can deploy the assembly
containing the exception information in two ways:
In C#, use at least the three common constructors when creating your own
exception classes.
Page 44
In most cases, use the predefined exceptions types. Define new exception
types only for programmatic scenarios. Introduce a new exception class to
enable a programmer to take a different action in code based on the
exception class.
Do not derive user-defined exceptions from the Exception base class. For
most applications, derive custom exceptions from the Application Exception
class.
Instead of sending error messages directly to the user, in case error occurs ,
the exception code should be returned and then based on users preferred
language appropriate messages should be shown to the user.
Return null for extremely common error cases. For example, File.Open
returns null if the file is not found, but throws an exception if the file is
locked.
Page 45
The stack trace begins at the statement where the exception is thrown and
ends at the catch statement that catches the exception. Be aware of this fact
when deciding where to place a throw statement.
Use exception builder methods. It is common for a class to throw the same
exception from different places in its implementation. To avoid excessive
code, use helper methods that create the exception and return it.
Page 46
Inc.")]
[assembly: AssemblyTrademark("Company")]
[assembly: AssemblyCulture("")]
[assembly:CLSCompliant(true)]
Page 47
Put copyright notice also on the top of every cs file. Following copyright
information should be used.
#region Copyright
reserved
(c)
2005-2006
Company
Inc.
All
rights
// **************************************************************
// Copyright (c) 2005 Company.
//
//The copyright to the computer software herein is proprietary
//and remains the property of Company. It may //be used and/or
copied only with the written consent of Company // or in
accordance with the terms and conditions //stipulated in the
agreement/contract under which this software //has been supplied.
// **************************************************************
#endregion
Note: You can modify templates in the Visual studio so that each time you add a
new file the copyright notice is automatically added to the created file.
E.g. To add copyright notice when a new class is created change the following
template(For VS .NET 2003)
<VS
Installation
Directory>\Microsoft
Visual
Studio
.NET
2003\VC#\VC#Wizards\CSharpAddClassWiz\Templates\1033\ NewCSharpFile.cs
All assembly references in the same solution should use relative path. (This is
by default in Visual Studio)
6 References:
http://msdn2.microsoft.com/en-us/library/ms229042(en-US,VS.80).aspx
http://www.gotdotnet.com/Team/FxCop/docs/rules/NamingRules.aspx
http://www.csharpfriends.com/Articles/getArticle.aspx?articleID=336
http://www.tech.purdue.edu/Cpt/Courses/cpt355/C_Sharp_Coding_Standards
_and_Guidelines.htm
http://www.icsharpcode.net/TechNotes/SharpDevelopCodingStyle03.pdf
Page 48
Appnedix A
Hungarian notation: It describes the practice of prefixing variable names with a
tag that indicates what kind of object or data they hold. Contrary to popular belief,
this does not mean that the prefix should indicate the data type of the variable, but,
rather, it should give someone reviewing the code a clue as to what the variable
contains and what it is intended to be used for. Prefixing a variable with a tag
indicating its data type is better known as System notation, and should not be used.
Example of Hungarian notation for variables:
int rowCount = 0;
int colCount = 0;
Notice that both variables have integer data types, and both are intended to hold a
count of something, but it is very clear that rowCount is a count of a rows, and
colCount is a count of columns.
Anyone reviewing the following code:
rowCount = userData.Columns.Count;
colCount = userData.Rows.Count;
would be able to spot an error in the usage of the variables.
Hungarian notation, when used properly, gives a readable quality to the code, and
makes code easier to write, debug, and maintain because it helps correct code look
correct, and incorrect code look incorrect.
Hungarian notation is not recommended in c# by Microsoft. Some of the reasons
why not to use Hungarian notations are as follows
The VS.NET IDE offers several ways to quickly identify an objects type:
You can often tell an identifiers type by the usage. This is particularly true in
OO environments where you often set an identifier to a new followed by the
type or when a method tells you what type it returns, such as
GetXmlReader() or LoadControl().
Page 49