C Sharp Coding Guidelines and Best Practices 2

Embed Size (px)

Citation preview

  • 8/18/2019 C Sharp Coding Guidelines and Best Practices 2

    1/49

    C# Coding Guidelines and Best Practices

    Pradeep Kumar Mishra Page 1

    Dot Net Development Open Book

    C# Coding Guidelines and Best Practices

    Pradeep Kumar Mishra

  • 8/18/2019 C Sharp Coding Guidelines and Best Practices 2

    2/49

    C# Coding Guidelines and Best Practices

    Pradeep Kumar Mishra Page 2

    1  INTRODUCTION ......................................................................................... 4 

    2  NAMING CONVENTIONS AND STYLE ................................................................. 4 

    2.1  Capitalization style ........................................................................... 4 

    2.1.1  Pascal case .................................................................................. 4 

    2.1.2  Camel case .................................................................................. 4 

    2.1.3  Uppercase ................................................................................... 4 

    2.1.4  Capitalization Summary ................................................................. 5 

    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  Static Fields ................................................................................. 9 

    2.2.7  Variables ..................................................................................... 9 

    2.2.8  Properties .................................................................................. 10 

    2.2.9  Events ...................................................................................... 11 

    2.2.10  Case sensitivity ....................................................................... 12 

    2.2.11  General ................................................................................. 12 

    3  CODING STYLE ........................................................................................ 15 

    3.1 

    Source Files .................................................................................. 15 

    3.2  Ordering ....................................................................................... 15 

    3.3  Indentation ................................................................................... 15 

    3.3.1 

    Wrapping Lines .......................................................................... 15 

    3.3.2  White Spaces ............................................................................. 15 

    3.4  Comments .................................................................................... 16 

    3.4.1  Implementation Comments .......................................................... 16 

    3.4.2 

    Documentation Comments ........................................................... 18 

    3.4.3  Comment Tokens ........................................................................ 18 

    3.5 

    Formatting .................................................................................... 19 

    3.6  Declaration ................................................................................... 19 

    3.6.1  Number of Declarations per Line ................................................... 19 

    3.6.2  Initialization ............................................................................... 19 

    3.6.3  Class and Interface Declarations ................................................... 19 

    3.7  Statements ................................................................................... 20 

  • 8/18/2019 C Sharp Coding Guidelines and Best Practices 2

    3/49

    C# Coding Guidelines and Best Practices

    Pradeep Kumar Mishra Page 3

    3.7.1  Simple Statements ..................................................................... 20 

    3.7.2  Return Statements ...................................................................... 20 

    3.7.3  If, if-else, if else-if else Statements ............................................... 20 

    3.7.4  For / Foreach Statements ............................................................. 21 

    3.7.5  While/do-while Statements ........................................................... 22 

    3.7.6  Switch Statements ...................................................................... 22 

    3.7.7  Try-catch Statements .................................................................. 23 

    4  BEST PRACTICES ..................................................................................... 23 

    4.1  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 

    5  PROJECT SETTINGS AND STRUCTURE ............................................................. 46 

    6  R EFERENCES: ......................................................................................... 48 

    APPNEDIX A ............................................................................................... 49 

  • 8/18/2019 C Sharp Coding Guidelines and Best Practices 2

    4/49

    C# Coding Guidelines and Best Practices

    Pradeep Kumar Mishra Page 4

    1  IntroductionQuality 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. It‟s not just the delivery but also the after delivery taskslike support gets impacted by coding standards followed by the development team.

    The standard helps in enforcing best practices and avoiding pitfalls and makesknowledge 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 closelyfollowed. Completed source code should reflect a harmonized style, as if a singledeveloper wrote the code in one session.

    2  Naming conventions and style

    2.1 Capitalization styleUse the following three conventions for capitalizing identifiers:

    2.1.1  Pascal case

    The first letter in the identifier and the first letter of each subsequent concatenated

    word are capitalized. You can use Pascal case for identifiers of three or more

    characters. For example: BackColor.

    2.1.2  Camel case

    The first letter of an identifier is lowercase and the first letter of each subsequent

    concatenated word is capitalized. For example: backColor.

    2.1.3  Uppercase

    All letters in the identifier are capitalized. Use this convention only for identifiers thatconsist of two or fewer letters. For example: System.IO, System.Web.UI.

  • 8/18/2019 C Sharp Coding Guidelines and Best Practices 2

    5/49

    C# Coding Guidelines and Best Practices

    Pradeep Kumar Mishra Page 5

    2.1.4  Capitalization Summary

    Identifier Rules for Naming Notes/Examples

    Class Pascal Case

    Attribute Class Pascal Case Has a suffix of Attribute

    Exception Class Pascal Case Has a suffix of Exception

    Constant Pascal Case

    Enum type Pascal Case

    Enum values Pascal Case

    Event Pascal Case

    Interface Pascal Case Has a prefix of I

    Local variable Camel Case

    Method Pascal Case

    Namespace Pascal Case

    Property Pascal Case

    Public Instance Field Pascal CaseRarely used (use aproperty instead)

    Protected Instance Field Camel CaseRarely used (use a

    property instead)

    Parameter Camel Case

    2.2 Naming rulesNaming rules make programs more comprehensible by facilitating them for reading.They can also give information about the function of the identifier, for example,

    whether it's a constant, package, or class, which can be helpful in understanding the

    code.

    How the various elements of the application are named is perhaps the most

    influential aids to understand the logical flow of an application is how the variouselements of the application are named. A name should tell "what" rather than "how."

    By avoiding names that expose the underlying implementation, which can change,

    you preserve a layer of abstraction that simplifies the complexity. For example, youcould use GetNextOrder() instead of GetNextArrayElement().

    A tenet of naming is that difficulty in selecting a proper name may indicate that youneed to further analyze or define the purpose of an item. Let names be long enoughmeaningfully however short enough avoid being wordy. Programmatically, a uniquename serves only to differentiate one item from another. Expressive names function

    as an aid to the human reader; therefore, it makes sense to provide a name that thehuman reader can comprehend. However, be certain that the names chosen are incompliance with the applicable rules and standards.

  • 8/18/2019 C Sharp Coding Guidelines and Best Practices 2

    6/49

    C# Coding Guidelines and Best Practices

    Pradeep Kumar Mishra Page 6

    Most of the content of the naming rules has been taken from Microsoft

    recommendations (link of the same has been given in the reference section).

    There is a widely accepted code analyzer tool called FxCop (See reference section)

    which also provide some guidelines. So if appropriate naming standards are notdefined in this document the FxCop Naming Rules should be used.

    2.2.1 Namespaces

    The general rule for namespace naming is:

    [].[].[].[]Example:

    Company.ProductName.Ecommerce.DataLayer;

      Do avoid the possibility of two published namespaces having the same name.

      Do not use department or project name as they change too frequently.

     

    Do use Pascal Case and Nouns.

      Do not use the underscore (“_”). 

      Do consider wider scope modules across an enterprise

    Example: Company.ProductName.Core or Company.Core 

      Do use whole, simple and descriptive words and avoid acronyms andabbreviations unless abbreviation is much more widely used than long form,

    such as URL, Xml etc.

      Do use plural namespace names where appropriate. For example, useSystem.Collections rather than System.Collection. Exceptions to this rule arebrand names and abbreviations. For example, use System.IO not System.IOs.

     

    Do not have namespaces and classes with the same name.

    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 use sparingly, abbreviations in class names.

      Do not use plural tense, use a second descriptive noun, or noun phraseinstead (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 interfacenames. 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 thederived 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.

  • 8/18/2019 C Sharp Coding Guidelines and Best Practices 2

    7/49

    C# Coding Guidelines and Best Practices

    Pradeep Kumar Mishra Page 7

      Do not use any underscores.

      Do use suffix „Exception‟ with custom exception class. 

    e.g. public class NoDataFoundException{ .. }

      Do use suffix „Attribute‟ with custom attribute class. 

    e.g public class PersistentEntity Attribute

      Do add the suffix Stream to types that inherit from System.IO.Stream.

    Example:

    public class InvoiceItemGroup { … } public class Invoice { … } 

    2.2.3  Method 

     

    Do name methods with Pascal Case

      Do name methods with active verb forms and imperatives (ProcessInvoice,

    SubmitTransaction). It is not necessary to include the noun name when theactive verb refers directly to the containing class.

    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 someoperation on a given object which describes the operation, such as

    CalculateInvoiceTotal(). 

      Do Not use elusive name like Analyze().

    2.2.4  Interfaces

      Do prefix interface names with the letter “I”, to indicate  that the type is an

    interface.

      Do name interfaces with nouns or noun phrases, or adjectives describingbehavior (what the implementation will be.). For example, IComponent

    (descriptive noun), ICustomAttributeProvider (noun phrase), and IPersistable

    (adjective).  Do use Pascal Case.

      Do use sparingly, abbreviations in interface names.

      Do not use plural tense (IComponentCollection instead of IComponents)

      Do not use any underscores.

      Do use similar names when defining a class/interface pair where the class is astandard implementation of the interface. The names should differ only by the

  • 8/18/2019 C Sharp Coding Guidelines and Best Practices 2

    8/49

    C# Coding Guidelines and Best Practices

    Pradeep Kumar Mishra Page 8

     “I”  prefix in the interface name. This approach is used for the interface

    IComponent and its standard implementation, Component.

    Example: 

    public interface IComponent { … } 

    public class Component : IComponent { … } public interface IServiceProvider{ … } public interface IFormatable { … } 

    2.2.5  Enums

      Do use Pascal Case for enums.

      Do use Pascal Case for enum value names.

      Do use sparingly, abbreviations in enum names.

      Do not use a family-name prefix on enum.

     

    Do not use any “Enum” suffix on enum types. 

      Do use a singular name for enums

      Do use a plural name for enumerations with bit fields as values also called

    flags enumerations.

    SearchOptions(bitwise flags)

      Do define enumerated values using an enum if they are used in a parameter

    or property. This gives development tools a chance at knowing the possiblevalues for a property or parameter.

    public enum TransactionType{

    Inquiry,Sale,Credit,Authorization,Capture,Void

    }

      Do use the Flags custom attribute if the numeric values are meant to bebitwise OR-ed together

    [Flags]public enum Bindings

    {

    CreateInstance,DefaultBinding,ExcatBinding,GetField,GetProperty,IgnoreCase,InvokeMethod,NonPublic,OABinding,SetField

  • 8/18/2019 C Sharp Coding Guidelines and Best Practices 2

    9/49

    C# Coding Guidelines and Best Practices

    Pradeep Kumar Mishra Page 9

    SetProperty,Static

    }

      Do use int as the underlying type of an enum. (An exception to this rule is ifthe 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 differentfrom 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.6  Static Fields 

      Do name static members with nouns, noun phrases, or abbreviations for

    nouns.

      Do name static members using Pascal Case.

     

    Do not use Hungarian-type prefixes on static member names (Definition ofHungarian notation is given in the Appendix A.)

    2.2.7  Variables

      Do use descriptive names such that a variable ‟s name that clearly indicateswhat the purpose of the variable is and what value it will hold.

      Do name variables using camel case.

      Do initialize variables at the point of declaration if possible.

      Do prefix private fields with an underscore (“_”) like _privateField. All othervariable must follow simply camel Case.

     

    Do prefer names based on a parameter‟s meaning, to names based on theparameter‟s type. It is likely that development tools will provide theinformation about type in a convenient way, so the parameter name can beput to better use describing semantics rather than type.

      Do use the “this” keyword when referring to members at a class‟s  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 nextversion, 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 use  “is”   for boolean variable which implies Yes/No or True/False values,such as isFound, or isSuccess.

      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 differfrom Boolean variables in that they may have more than two possible values.

    Instead of orderFlag, use a more descriptive name such as orderStatus.

  • 8/18/2019 C Sharp Coding Guidelines and Best Practices 2

    10/49

    C# Coding Guidelines and Best Practices

    Pradeep Kumar Mishra Page 10

      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 forshort-loop indexes only.

      Do not use all uppercase with underscores between words for constants, suchas NUM_DAYS_IN_WEEK. Constants follow the same naming rules as

    properties. The aforementioned constant would be named NumDaysInWeek.

      Do not use Hungarian-type prefixes. (Definition of Hungarian notation is givenin the Appendix A.)

    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

     

    Do name properties using noun or noun phrases

      Do name properties with Pascal Case

      Do not include class names in the name of class properties, such as

    Book.BookTitle. Instead, use Book.Title. This is the case with all object-

    oriented languages.

  • 8/18/2019 C Sharp Coding Guidelines and Best Practices 2

    11/49

    C# Coding Guidelines and Best Practices

    Pradeep Kumar Mishra Page 11

      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 propertybe 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 thatfirst gets the value of the Color property (of type int) and then accesses amember of that value (which would have to be an instance member of

    System.Int32).

    2.2.9  Events 

      Do name event handlers with the “EventHandler” suffix.

    public delegate void MouseEventHandler(object sender,

    MouseEvent e);

      Do use two parameters named sender  and e. The sender parameter

    represents the object that raised the event, and this parameter is always of

    type object, even if it is possible to employ a more specific type. The stateassociated with the event is encapsulated in an instance e of an event class.

    Use an appropriate and specific event class for its type.

    public delegate void MouseEventHandler(object sender,

    MouseEvent e);

      Do name event argument classes with the “EventArgs” suffix.

    public class MouseEventArgs : EventArgs

    {int x;int y;public MouseEventArgs(int x, int y)

    { this.x = x; this.y = y; }public int X { get { return x; } }public int Y { get { return y; } }

      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 apast-tense verb to represent post-event. For example, a Close event that canbe canceled should have a Closing event and a Closed event.

  • 8/18/2019 C Sharp Coding Guidelines and Best Practices 2

    12/49

    C# Coding Guidelines and Best Practices

    Pradeep Kumar Mishra Page 12

      Do Use an „–ing‟  and „–ed‟  form to express pre-events and postevents.

    Do not use a pattern like BeginXxx and EndXxx. If you want to providedistinct events for expressing a point of time before and a point of time after

    a certain occurrence such as a validation event, do not use a pattern likeBeforeValidation and AfterValidation. Instead, use a Validating and Validated

    pattern.

    public event ControlEventHandler ControlAdded  

    {//..

    }

    2.2.10  Case sensitivity

    Don‟t  use names that require case sensitivity. Components might need to beusable from both case-sensitive and case-insensitive languages. Since case-

    insensitive languages cannot distinguish between two names within the samecontext that differ only by case, components must avoid this situation.

    Examples of what not to do:

      Don‟t have two namespaces whose names differ only by case.

    namespace ee.cummings;namespace Ee.Cummings;

      Don‟t have a method with two parameters whose names differ only by case.

    void F(string a, string A)

      Don‟t have a namespace with two types whose names differ only by case.

    System.WinForms.Point p;System.WinForms.POINT p;

     

    Don‟t have a type with two methods whose names differ only by case.

    void f();void F();

    2.2.11  General

      Always use „US English‟. 

      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 cancollapse within the Visual Studio IDE. What code regions enable you to do isgroup 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 

  • 8/18/2019 C Sharp Coding Guidelines and Best Practices 2

    13/49

    C# Coding Guidelines and Best Practices

    Pradeep Kumar Mishra Page 13

    Please note that regions can be nested but they can‟t overlap the other block

    statements.

      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 

      Avoid fully qualified name. Use the using statement instead.

      All member variables should be declared at the top of a class definition.

    public class MyClass

    {

    int _number

    int _name;

    public void SomeMethod()}

      Implementation details, in particular type specifications, should not be

    mentioned in the name of a descriptor. This is a common trait in procedurallanguages like Visual Basic where lowercase prefixes are used to encode thedata type in the name of the identifier, such as oInvoice. This approach is not

    applicable to contemporary languages where the aforementioned identifier is

    written simply as Invoice.

      Names with semantic content are preferred to names with type specifications

    (sizeOfArray instead of anInteger).

      Minimize the use of abbreviations. If abbreviations are used, be consistent in

    their use. An abbreviation should have only one meaning and likewise, eachabbreviated word should have only one abbreviation. For example, if usingmin to abbreviate minimum, do so everywhere and do not later use it to

    abbreviate minute.

      When naming methods, include a description of the value being returned,such as GetCurrentCustomerName().

      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()

    {

    …. 

  • 8/18/2019 C Sharp Coding Guidelines and Best Practices 2

    14/49

    C# Coding Guidelines and Best Practices

    Pradeep Kumar Mishra Page 14

    }

    //Avoid

    if(ValidateInput())

    {

    ...

    }

    //Correct

    bool isValidInput = ValidateInput();

    if(isValidInput)

    {

    ...

    }

      Do not use letters that can be mistaken for digits, and vice versa. Tocreate obfuscated code, use very short, meaningless names formed fromthe 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 loopvariable 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 stylewhile (condition != true) // also wrongwhile (((condition == true) == true) == true) // where do youstop?while (booleanCondition) // OK

     

  • 8/18/2019 C Sharp Coding Guidelines and Best Practices 2

    15/49

    C# Coding Guidelines and Best Practices

    Pradeep Kumar Mishra Page 15

    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 Invoiceshould have name Invoice.cs.

      Consider breaking apart a file as it approaches 1500 lines.

    3.2 Ordering

      C# source files have the following ordering:

    1.  using statements

    2.  namespace statement

    3.  Class and interface declarations

      Group all framework namespaces together and put custom or third partynamespaces underneath.

    using System;

    using System.Data;

    using Company.ProductName.Core;

    using Company.ProductName.Data;

    3.3  Indentation

    3.3.1 

    Wrapping LinesWhen an expression will not fit on a single line, break it up according to thesegeneral 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 whichis used.

    Example

    SomeMethod(longExpresssion1, longExpression2,longExpression3)

    3.3.2  White Spaces

    Always use 4 spaces for indentation. Since we use Visual studio as IDE hence it‟sbetter to use tabs over there. (By default tab is set to 4 spaces and this will reduce

    typing.)

  • 8/18/2019 C Sharp Coding Guidelines and Best Practices 2

    16/49

    C# Coding Guidelines and Best Practices

    Pradeep Kumar Mishra Page 16

    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 insystem documentation. 

    Implementation comments are meant for commenting out code or for commentsabout the particular implementation. Doc comments are meant to describe the

    specification of the code, from an implementation-free perspective, to be read bydevelopers 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 abusiness rule that says that large orders get a discount? Is there a limited-timespecial 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:

      When modifying code, always keep the commenting around it up to date.

    • Comments should consist of complete sentences and follow active languagenaming responsibilities ( Adds the element instead of The element is added ).

    • At the beginning of every routine, XML documentation is used to indicate theroutine's purpose, assumptions, and limitations. A boilerplate comment should be a

    brief introduction to understand why the routine exists and what it can do.

      Avoid adding comments at the end of a line of code; end-line comments makecode 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 toallot of subjective interpretations. Use your best judgment to determine anappropriate level of what it means for code to be not really obvious.

      Throughout the application, construct comments using a uniform style, withconsistent punctuation and structure.

    3.4.1  Implementation Comments

      Block Comments

  • 8/18/2019 C Sharp Coding Guidelines and Best Practices 2

    17/49

    C# Coding Guidelines and Best Practices

    Pradeep Kumar Mishra Page 17

    Block comments are used to provide descriptions of files, methods, data

    structures and algorithms. Block comments may be used at the beginning of eachfile. They can also be used in other places, such as within methods. Block

    comments inside a function or method should be indented to the same level asthe code they describe.

    A blank line to set it apart from the rest of the code should precede a block

    comment.

     // Here is a block comment

     // that breaks across multiple

     // lines.

      Single-Line Comments

    Short comments can appear on a single line indented to the level of the code that

    follows. If a comment can't be written in a single line, it should follow the blockcomment format. A single-line comment should be preceded by a blank line.

    Here's an example of a single-line comment in code.if (condition){// Handle the condition....}

      Trailing CommentsVery short comments can appear on the same line as the code they describe, butshould be shifted far enough to separate them from the statements. If more than

    one short comment appears in a chunk of code, they should all be indented tothe same tab setting.Here's an example of a trailing comment in C# code:ss = s1 + s2 + s3;  //add the three scores into the sum 

    a = float(ss) / x; 

    //calculate the mean of the scores 

      Code-Disabling CommentsThe // comment delimiter can comment out a complete line or only a partial line.

    Code-disabling comment delimiters are found in the first position of a line of code

    flush with the left margin. Visual Studio .NET provides for bulk commenting byselecting the lines of code to disable and pressing CTRL+K, CTRL+C. Touncomment, use the CTRL+K, CTRL+U chord.

    We should try not to check in the commented code as that may confuse other

    developers working on the same code.(Unless there is very specific reason. CodeReviewer should check this.)

    The following is an example of code-disabling comments:

    if (foo > 1){// Do a double-flip....}else{return false; // Explain why here.}// if (bar > 1)

  • 8/18/2019 C Sharp Coding Guidelines and Best Practices 2

    18/49

    C# Coding Guidelines and Best Practices

    Pradeep Kumar Mishra Page 18

    // {//// // Do a triple-flip.// ...// }// else// {// return false;// }

    3.4.2  Documentation Comments

    C# provides a mechanism for developers to document their code using XML.   XMLdocumentation starts with ///.

    Consider following points while writing XML documentation… 

      The documentation must be well-formed XML. If the XML is not well-formed, a

    warning is generated and the documentation file will contain a commentsaying that an error was encountered.

      Developers are not free to create their own set of tags.

      There is a recommended set of tags.

      Some of the recommended tags have special meanings:

    o  The tag is used to describe parameters. If used, thecompiler will verify that the parameter exists and that all parameters

    are described in the documentation. If the verification failed, thecompiler issues a warning.

    o  The cref attribute can be attached to any tag to provide a reference to

    a code element. The compiler will verify that this code element exists.

    If the verification failed, the compiler issues a warning. The compiler

    also respects any using statements when looking for a type describedin the cref attribute.

    o  The tag is used by IntelliSense inside Visual Studio todisplay additional information about a type or member.

    If you need to give information about a class, interface, variable, or method that isn'tappropriate 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 constructordefinition block, because C# associates documentation comments with the first

    declaration after the comment.

    3.4.3 

    Comment Tokens

    When you add comments with comment tokens to your code, you automatically add

    shortcuts to the Task List window. Double-click any comment displayed in the TaskList to move the insertion point directly to the line of code where the comment

    begins.

    Note: Comments in HTML, .CSS, and .XML markup are not displayed in the Task

    List.

  • 8/18/2019 C Sharp Coding Guidelines and Best Practices 2

    19/49

    C# Coding Guidelines and Best Practices

    Pradeep Kumar Mishra Page 19

    To add a comment hyperlink to the Task List window, enter the comment marker.

    Enter TODO, HACK, or UNDONE. Add the Comment text.

    // ToDo: Fix this later

    // Hack: Temporary solution to be enhanced later

    3.5  Formatting

    Visual studio 2005 has an auto formatting feature and overall we should follow itsstyle 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())

    {

    ...

    }

    3.6.3  Class and Interface Declarations

    When coding C# classes and interfaces, the following formatting rules should be

    followed:  No space between a method name and the parenthesis "(" starting its

    parameter list.

      The opening brace "{" appears in the next line after the declarationstatement.

      The closing brace " }" starts a line by itself indented to match itscorresponding opening brace.

  • 8/18/2019 C Sharp Coding Guidelines and Best Practices 2

    20/49

    C# Coding Guidelines and Best Practices

    Pradeep Kumar Mishra Page 20

    This is the formatting followed by VS2005 auto formatter.

    For example :

    class MySample : MyClass, IMyInterface

    {

    int myInt;

    public MySample(int myInt)

    {

    this.myInt = myInt ;

    }

    void Inc()

    {

    ++myInt;

    }

    void EmptyMethod()

    {

    }

    }

    3.7  Statements

    3.7.1  Simple Statements

    Each line should contain only one statement.

    3.7.2  Return Statements

    A return statement should not use outer most parentheses.

    Don't use : return (n * (n + 1) / 2);

    use : return n * (n + 1) / 2;

    3.7.3  If, if-else, if else-if else Statements

    if, if-else and if else-if else statements should look like this:if (condition)

    {

    DoSomething();

    ...

    }

    if (condition)

  • 8/18/2019 C Sharp Coding Guidelines and Best Practices 2

    21/49

    C# Coding Guidelines and Best Practices

    Pradeep Kumar Mishra Page 21

    {

    DoSomething();

    ...

    }

    else

    {

    DoSomethingOther();

    ...

    }

    if (condition)

    {

    DoSomething();

    ...

    }

    else if (condition)

    {

    DoSomethingOther();

    ...

    }

    else

    {

    DoSomethingOtherAgain();...

    }

    Note: Always use brackets even if there is only one statement in the loop.

    E.g. if (connection!=null)

    {

    Connection.close();

    }

    3.7.4  For / Foreach Statements

    A for statement should have following form:

    for (int i = 0; i < 5; ++i)

    {

    ...

    }

  • 8/18/2019 C Sharp Coding Guidelines and Best Practices 2

    22/49

    C# Coding Guidelines and Best Practices

    Pradeep Kumar Mishra Page 22

    A foreach should look like :

    foreach (int i in IntList)

    {

    ...

    }

    3.7.5 While/do-while Statements

    A while statement should be written as follows:

    while (condition)

    {

    ...

    }

    An empty while should have the following form:

    while (condition) ;

    A do-while statement should have the following form:

    do 

    {

    ...

    } while (condition);

    3.7.6  Switch Statements

    Always use default case with switch statement. A switch statement should be offollowing form

    switch (condition)

    {

    case A:

    ...

    break;

    case B:

    ...

    break;

    default:

    ...

    break;

  • 8/18/2019 C Sharp Coding Guidelines and Best Practices 2

    23/49

    C# Coding Guidelines and Best Practices

    Pradeep Kumar Mishra Page 23

    }

    3.7.7 

    Try-catch Statements

    A try-catch statement should follow this form:try 

    {

    ...

    }

    catch (Exception e)

    {

    }

    or

    try

    {

    ...

    }

    catch (Exception e)

    {

    ...

    }

    finally

    {

    ...

    }

    4  Best PracticesThis 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.

    http://www.codeproject.com/http://www.codeproject.com/http://www.gotdotnet.com/team/fxcop/http://www.gotdotnet.com/team/fxcop/http://www.gotdotnet.com/team/fxcop/http://www.gotdotnet.com/team/fxcop/http://www.codeproject.com/

  • 8/18/2019 C Sharp Coding Guidelines and Best Practices 2

    24/49

    C# Coding Guidelines and Best Practices

    Pradeep Kumar Mishra Page 24

    4.1 Performance

      Prefer the Length property when checking string sizeString comparison involves unnecessary overhead. If all you need is to checkwhether the string is empty, use the Length property.

    Code snippets://NO

    if ( str != “”)//comparison of two strings 

    {

    ...

    }

    //YES

    if ( str.Length > 0)

    {

    ...

    }

      Prefer StringBuilder instead of string concatenation.C# string is immutable, i.e., cannot be altered. When you alter a string, youare 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:

    //NOstring strConcat;ArrayList arrayOfStrings = new ArrayList();arrayOfStrings.Add("a");arrayOfStrings.Add("b");foreach (string s in stringContainer) {

    strConcat += s;}

    //YESStringBuilder sbConcat = new StringBuilder ();foreach (string s in arrayOfStrings ) {

    sbConcat.append(s);

    }

    For very simple concatenation we should directly add them asfollows:

    //Yesreturn a + b + c;

    //NOStringBuilder a = new StringBuilder();

  • 8/18/2019 C Sharp Coding Guidelines and Best Practices 2

    25/49

    C# Coding Guidelines and Best Practices

    Pradeep Kumar Mishra Page 25

    a.Append(b);a.Append(c);return a;

      Avoid unsealed attributes.

    The .NET Framework class library provides methods for retrieving custom

    attributes. By default, these methods search the attribute inheritancehierarchy; for example System.Attribute.GetCustomAttribute searches for the

    specified attribute type, or any attribute type that extends the specifiedattribute type. Sealing the attribute eliminates the search through the

    inheritance hierarchy, and can improve performance.Example:using System;

    namespace PerformanceLibrary{

    //AvoidUnsealedAttributes.

    [AttributeUsage(AttributeTargets.Class|AttributeTargets.Struct)]public sealed class DeveloperAttribute: Attribute{

    private string nameValue;public DeveloperAttribute(string name){

    nameValue = name;}

    public string Name{

    get

    {return nameValue;

    } }

    }

    }

      Avoid Boxing and UnBoxing as much as possible.Boxing a value of a value-type consists of two operations:

    1. 

    Allocating an object instance.2.  Copying the value-type value into that instance.

    Given the above, you should avoid Boxing as much as you can. If you intend to

    work with ArrayList, for example, do not declare your data type as struct (Valuetype) because ArrayList works with Object (Reference type) and every time you

    add an instance of the struct or run over the container, in a loop, a Boxing

    process will occur.The following happens when you copy one of the collection items value into thestruct:

    http://msdn.microsoft.com/library/en-us/cpref/html/frlrfSystemAttributeClassGetCustomAttributeTopic.asphttp://msdn.microsoft.com/library/en-us/cpref/html/frlrfSystemAttributeClassGetCustomAttributeTopic.asphttp://msdn.microsoft.com/library/en-us/cpref/html/frlrfSystemAttributeClassGetCustomAttributeTopic.asp

  • 8/18/2019 C Sharp Coding Guidelines and Best Practices 2

    26/49

    C# Coding Guidelines and Best Practices

    Pradeep Kumar Mishra Page 26

      Casting.

      Copy the value.

    Note: Collections expect object type.

    Code snippets:

    //NOstruct st { public Int i; }Arraylist arr = new ArrayList();for (int i=0 ; i< count; i++){st s;s.i = 4;arr.item.add(st) ; //

  • 8/18/2019 C Sharp Coding Guidelines and Best Practices 2

    27/49

    C# Coding Guidelines and Best Practices

    Pradeep Kumar Mishra Page 27

    The .NET Framework runs C# assemblies using the JIT compiler. Each code that

    is executed for the first time is being compiled. In case of heavy and longinitialization in your assembly, you might want to use the nGen .NET tool.

    "The nGen creates a native image from a managed assembly and installs it into

    the native image cache on the local computer.

    Once you create a native image for an assembly, the runtime automatically usesthat native image each time it runs the assembly. You do not have to perform

    any additional procedures to cause the runtime to use a native image. RunningNgen.exe on an assembly allows the assembly to load and execute faster,because it restores code and data structures from the native image cache ratherthan generating them dynamically." (MSDN 2005)

    You do not have to lose the advantage of JIT compilation, because you can call

    the nGen command on the installation machine through your project setup,using:

    ngen [options] [assemblyName |assemblyPath ]

      Prefer 'for' over 'foreach'.

    'foreach' and 'for' statements serve the same goal - run in loop over block ofstatements.

    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 cansay that foreach is a private case of for.

    In the code snippets below, we can see that both loop blocks produce the sameresults, 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:

    //foreachint[] arrayOfInts= new int[5];int sum= 0;foreach(int i arrayOfInts) {

    sum+= i;}

    //forint[] arrayOfInts= new int[1];int sum= 0;for(int i = 0; i < arrayOfInts.Length; i++) {

    sum+= arrayOfInts[i];

  • 8/18/2019 C Sharp Coding Guidelines and Best Practices 2

    28/49

    C# Coding Guidelines and Best Practices

    Pradeep Kumar Mishra Page 28

    }

      Do not cast unnecessarily.Duplicate casts degrade performance, especially when the casts are

    performed in compact iteration statements. For explicit duplicate cast

    operations, store the result of the cast in a local variable and use the localvariable instead of the duplicate cast operations.

    If the C# is operator is used to test whether the cast will succeed before theactual cast is performed, consider testing the result of the as  operator

    instead. This provides the same functionality without the implicit castoperation performed by the is operator.

    Example:namespace PerformanceLibrary{

    public sealed class SomeClass{

    private SomeClass() {}

    // NO.public static void UnderPerforming(ArrayList list){

    foreach(object obj in list){

    // The 'is' statement performs a cast operation.if(obj is Control){

    // The 'as' statement performs a duplicate castoperation.

    Control aControl = obj as Control;// Use aControl.

    }

    }}

    // Yes.public static void BetterPerforming(ArrayList list){

    foreach(object obj in list){

    Control aControl = obj as Control;if(aControl != null){

    // Use aControl.}

    }}}

    }

    4.2 Usage

      Use string.Empty instead of “” 

  • 8/18/2019 C Sharp Coding Guidelines and Best Practices 2

    29/49

    C# Coding Guidelines and Best Practices

    Pradeep Kumar Mishra Page 29

    //Avoid

    string name = “”; 

    //Correct

    string name = string.Empty;

      Use the 'checked' keyword to avoid overflow.

    Code snippets:

    //NOshort shortNum;int i = 32768;shortNum = (short) i;// problem after statment excution// the shortNum variable has an uninitialized value,

    //YEStry {shortNum = checked((short)i); // solution

    }catch(OverflowException efx) {}

      Use Explicit interface to 'hide' the implementation of an interfaceImplementing 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 definitionpublic 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.

  • 8/18/2019 C Sharp Coding Guidelines and Best Practices 2

    30/49

    C# Coding Guidelines and Best Practices

    Pradeep Kumar Mishra Page 30

    A writable collection property allows a user to replace the collection with an

    entirely different collection. A read-only property stops the collection frombeing replaced while still allowing the individual members to be set. If

    replacing the collection is a goal, the preferred design pattern is to include amethod to remove all the elements from the collection and a method to re-

    populate the collection.Example: The following example shows a type with a writable collection

    property and shows how the collection can be replaced directly. In addition,

    the preferred manner of replacing a read-only collection property using Clearand AddRange methods is shown.

    namespace UsageLibrary{

    public class WritableCollection{

    ArrayList strings;

    public ArrayList SomeStrings

    { get { return strings; }

    // Violates the rule.set { strings = value; }

    }

    public WritableCollection(){

    strings = new ArrayList(new string[] {"IEnumerable", "ICollection", "IList"}

    );}

    }

    class ReplaceWritableCollection{

    static void Main(){

    ArrayList newCollection = new ArrayList(new string[] {"a", "new", "collection"} );

    // strings is directly replaced with newCollection.WritableCollection collection = new 

    WritableCollection();collection.SomeStrings = newCollection;

    // newCollection is added to the cleared stringscollection.collection.SomeStrings.Clear();collection.SomeStrings.AddRange(newCollection);

    }}

  • 8/18/2019 C Sharp Coding Guidelines and Best Practices 2

    31/49

    C# Coding Guidelines and Best Practices

    Pradeep Kumar Mishra Page 31

      Use @ to ease the work with literal paths.

    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 publicexposed 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)]

      Define destructor and implement IDisposable interface for classesthat use native resource directly.

    You should define a destructor whenever you use native code in your assembly,i.e., use types that are not managed by the garbage collector. The compiler

    changes the destructor method to Finalize method (can be seen in the MSIL usingthe ILDasm.exe).

    The Garbage collector marks a class with destructor as Finalized and calls theFinalize method while destructing the object. This behavior guarantees that your

    release of resources in the destructor will occur.But, what if you want to release the resources immediately? For this purpose,you should implement the IDisposable interface and call the Dispose method

    when you want to release the object.Note 1: Do not use destructor if your class does not use native / unmanaged

    resources. If you do so, you create unnecessary work for the garbage collector.

    Note 2: If you implement the IDisposable and a destructor, you should call the

    Dispose method from the destructor to force the object to release resourcesimmediately.

    Code snippets:

    ~my class {if ( true == b){}

    }

    //The MSIL code:protected override void Finalize(){try {

  • 8/18/2019 C Sharp Coding Guidelines and Best Practices 2

    32/49

    C# Coding Guidelines and Best Practices

    Pradeep Kumar Mishra Page 32

    if ( true == b){}

    }finally { base.Finalize();}}

     

    Avoid the use of GC.Collect.The GC.Collect method forces garbage collection of all generations.

    The performance is hurt during the call to GC.Collect, the application execution is

    paused. Moreover, the method might cause the promotion of short lived objectsto a higher generation, i.e., those object live longer than it should in the first

    place.If you must use it in order to reclaim the maximum amount of available memory,

    use the method only on generation 0.

    Code snippets:

    //No:

    GO.Collect();//Yes:GC.Collect(0);

    4.3 Design  Abstract type should not have public constructors

    Constructors on abstract types can only be called by derived types. Because

    public constructors create instances of a type, and you cannot create instances ofan abstract type, an abstract type with a public constructor is incorrectlydesigned.

    Example:namespace DesignLibrary{

    public abstract class BadAbstractClassWithConstructor{

    //WRONG: AbstractTypesShouldNotHaveConstructors.public BadAbstractClassWithConstructor(){// Add constructor logic here.}

    }

    public abstract class GoodAbstractClassWithConstructor{

    protected GoodAbstractClassWithConstructor(){

    // Add constructor logic here.}

    }}

      Consider passing base types as parameters.When a base type is specified as a parameter in a method declaration, any typederived from the base type can be passed as the corresponding argument to the

  • 8/18/2019 C Sharp Coding Guidelines and Best Practices 2

    33/49

    C# Coding Guidelines and Best Practices

    Pradeep Kumar Mishra Page 33

    method. When the argument is used inside the method body, the specific method

    that is executed depends on the type of the argument. If the additionalfunctionality provided by the derived type is not required, use of the base type

    allows the method to be more widely utilized.Example:

    namespace DesignLibrary{

    public class StreamUser{

    int anInteger;

    public void ManipulateFileStream(FileStream stream){

    while((anInteger = stream.ReadByte()) != -1){

    // Do something.}

    }

    public void ManipulateAnyStream(Stream anyStream){

    while((anInteger = anyStream.ReadByte()) != -1){

    // Do something.}

    }}

    class TestStreams{

    static void Main(){

    StreamUser someStreamUser = new StreamUser();MemoryStream testMemoryStream = new MemoryStream(new byte[]

    {});using(FileStream testFileStream =

    new FileStream("test.dat", FileMode.OpenOrCreate)){

    // Cannot be used with testMemoryStream.someStreamUser.ManipulateFileStream(testFileStream);

    someStreamUser.ManipulateAnyStream(testFileStream);someStreamUser.ManipulateAnyStream(testMemoryStream);

    }}

    }

    }

      Enums should have zero valueThe default value of an un-initialized enumeration, like other value types, is zero.A non-flags attributed enumeration should define a member with the value of

    zero so that the default value is a valid value of the enumeration. If appropriate,name the member 'None'. Otherwise, assign zero to the most commonly used

    member. Note that if the value of the first enumeration member is not set in the

    declaration, its value is zero by default.

  • 8/18/2019 C Sharp Coding Guidelines and Best Practices 2

    34/49

    C# Coding Guidelines and Best Practices

    Pradeep Kumar Mishra Page 34

    If an enumeration that has the FlagsAttribute  applied defines a zero-valued

    member, its name should be 'None' to indicate that no values have been set inthe enumeration. Using a zero-valued member for any other purpose is contrary

    to the use of the FlagsAttribute  in that the AND and OR bitwise operators areuseless with the member. This implies that only one member should be assigned

    the value zero. Note that if there are multiple members with the value zero in aflags-attributed enumeration, Enum.ToString()  returns incorrect results for

    members that are not zero.

    Example:

    public enum TraceLevel

    {

    Off = 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,

    }

      Mark assemblies with ComVisible. 

  • 8/18/2019 C Sharp Coding Guidelines and Best Practices 2

    35/49

    C# Coding Guidelines and Best Practices

    Pradeep Kumar Mishra Page 35

    The ComVisibleAttribute  attribute determines how COM clients access

    managed code. Good design dictates that assemblies explicitly indicate COMvisibility. COM visibility can be set for an entire assembly and then overridden

    for individual types and type members. If the attribute is not present, thecontents of the assembly are visible to COM clients.

    [assembly: ComVisible(false)] //can be true or false

      Properties should not be write only. Get accessors provide read access to a property and set accessors providewrite access. While it is acceptable and often necessary to have a read-only

    property, the design guidelines prohibit the use of write-only properties

    because allowing a user to set a value, and then preventing the user fromviewing the value does not provide any security. Also, without read access,

    the state of shared objects cannot be viewed, which limits their usefulness.

    Example:public class BadClassWithWriteOnlyProperty

    {string someName;

    // Violates rule PropertiesShouldNotBeWriteOnly.public string Name{

    set{

    someName = value;}

    }}

    public class GoodClassWithReadWriteProperty

    {string someName;

    public string Name{

    get{

    return someName;}set{

    someName = value;}

    }} 

      Do not use string as type for URI parameters/properties or URIreturn values. 

    A string representation of a URI is prone to parsing and encoding errors,and can lead to security vulnerabilities. If a method takes a string

    representation of a URI, a corresponding overload should be provided that

  • 8/18/2019 C Sharp Coding Guidelines and Best Practices 2

    36/49

    C# Coding Guidelines and Best Practices

    Pradeep Kumar Mishra Page 36

    takes an instance of the Uri class, which provides these services in a safe

    and secure manner.

    Example:

    namespace DesignLibrary

    {

    public class ErrorProne

    {

    string someUri;

    // Violates rule UriPropertiesShouldNotBeStrings.

    public string SomeUri

    {

    get { return someUri; }

    set { someUri = value; }

    }

    // Violates rule UriParametersShouldNotBeStrings.

    public void AddToHistory(string uriString) { }

    // Violates rule UriReturnValuesShouldNotBeStrings.

    public string GetRefererUri(string httpHeader)

    {

    return "http://www.adventure-works.com";

    }

    }

    public class SaferWay

    {

    Uri someUri;

    // To retrieve a string, call SomeUri.ToString().// To set using a string, call SomeUri = new

    Uri(string).

    public Uri SomeUri

    {

    get { return someUri; }

    set { someUri = value; }

  • 8/18/2019 C Sharp Coding Guidelines and Best Practices 2

    37/49

    C# Coding Guidelines and Best Practices

    Pradeep Kumar Mishra Page 37

    }

    public void AddToHistory(string uriString)

    {

    // Check for UriFormatException.

    AddToHistory(new Uri(uriString));

    }

    public void AddToHistory(Uri uriType) { }

    public Uri GetRefererUri(string httpHeader)

    {

    return new Uri("http://www.adventure-works.com");

    }

    }

    }

    4.4 Globalization  Do not hardcode locale specific strings.

    Example:namespace GlobalizationLibrary{

    class WriteSpecialFolders{

    static void Main(){

    string string0 = "C:";

    // Do Not. string string1 = @"\Documents and Settings";string string2 = @"\All Users";string string3 = @"\Application Data";Console.WriteLine(string0 + string1 + string2 +

    string3);

    // Do useConsole.WriteLine(Environment.GetFolderPath(

    Environment.SpecialFolder.CommonApplicationData));}

    }} 

      Do pass IFormat provider and CultureInfo. 

  • 8/18/2019 C Sharp Coding Guidelines and Best Practices 2

    38/49

    C# Coding Guidelines and Best Practices

    Pradeep Kumar Mishra Page 38

    When a CultureInfo  or System.IFormatProvider object is not supplied,

    the default value supplied by the overloaded member might not have theeffect that you want in all locales. Also, .NET Framework members choose

    default culture and formatting based on assumptions that might not becorrect for your code. To ensure the code works as expected for your

    scenarios, you should supply culture-specific informationExample:

    namespace GlobalLibGlobalLibrary{

    public class IFormatProviderTest{

    public static void Main(){

    string dt = "6/4/1900 12:15:12";

    // The default behavior of DateTime.Parse is to use// the current culture.

    // Here IFormatProvider has not been specified.DateTime myDateTime = DateTime.Parse(dt);Console.WriteLine(myDateTime);

    //This gives out put as 6/4/1900 12:15:12 PM

    // Change the current culture to the required culture (e.gFrench),// and parsing the same string yields a different value.

    Thread.CurrentThread.CurrentCulture = new CultureInfo("Fr-fr", true);

    myDateTime = DateTime.Parse(dt);

    Console.WriteLine(myDateTime);

    //This gives out put as 06/04/1900 12:15:12

    }}

    }

    4.5  Security

      Array fields should not be read onlyWhen you apply the readonly modifier to a field that contains an array, the

    field cannot be changed to refer to a different array; however, the elements ofthe array stored in a read-only field can be changed. Code that makesdecisions or performs operations based on the elements of a publicly accessible

    read-only array might contain an exploitable security vulnerability.

    Example:public class MyClassWithReadOnlyArrayField{

  • 8/18/2019 C Sharp Coding Guidelines and Best Practices 2

    39/49

    C# Coding Guidelines and Best Practices

    Pradeep Kumar Mishra Page 39

    // The field grades is public, and therefore vulnerable to anycaller.

    public readonly int[] grades = {90, 90, 90};

    // The field privateGrades is private, but is still vulnerablebecause it is returned to callers by the GetPrivateGrades method.

    private readonly int[] privateGrades = {90, 90, 90};private readonly int[] securePrivateGrades = {90, 90, 90};

    // Making the array private does not protect it because it ispassed to others.

    public int[] GetPrivateGrades(){

    return privateGrades;}

    }

     

    Asserts require security demandsAsserting security permission without performing any security checks canleave an exploitable security weakness in your code

    SecurityPermission securePermission

    = new SecurityPermission(PermissionState.Unrestricted);

    /*Demand some permission(s) that all callers must have before

    you will assert permission on their behalf.

    In this example, all callers are required to have all security

    permissions before permission to access environment variables is

    asserted.

    */

    securePermission.Demand();

    //If the demand fails, a SecurityException is thrown.

      Public types that implement non-public interfaces should be sealedInterface methods have public accessibility, which cannot be changed by the

    implementing type. An internal interface creates a contract that is not intended

    to be implemented outside the assembly that defines the interface. A publictype that implements a method of an internal interface using the virtual 

    modifier allows the method to be overridden by a derived type that is outside

    the assembly. If a second type in the defining assembly calls the method andexpects an internal-only contract, behavior might be compromised when,instead, the overridden method in the outside assembly is executed. This

    creates security vulnerability.// Internal by default.

    interface IValidate{

    bool UserIsValidated();}

  • 8/18/2019 C Sharp Coding Guidelines and Best Practices 2

    40/49

    C# Coding Guidelines and Best Practices

    Pradeep Kumar Mishra Page 40

    public class BaseImplementation : IValidate{

    public virtual bool UserIsValidated(){

    return false;}

    }

    public class UseBaseImplementation{

    public void SecurityDecision(BaseImplementationsomeImplementation)

    {if(someImplementation.UserIsValidated() == true){

    Console.WriteLine("Account number & balance.");}else{

    Console.WriteLine("Please login.");}

    }} 

      Virtual methods and their Overrides require the same Link Demandstatus.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 methodEx: 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 thisimplementation does not.

    object ITestOverrides.GetFormat(Type formatType){

    return (formatType == typeof(OverridesAndSecurity) ?this : null);

    }

    // These two methods are overridden by DerivedClass andDoublyDerivedClass.

    [EnvironmentPermissionAttribute(SecurityAction.LinkDemand,Unrestricted=true)]

    public virtual void DoSomething()

  • 8/18/2019 C Sharp Coding Guidelines and Best Practices 2

    41/49

    C# Coding Guidelines and Best Practices

    Pradeep Kumar Mishra Page 41

    {Console.WriteLine("Doing something.");

    }

    public virtual void DoSomethingElse(){

    Console.WriteLine("Doing some other thing.");}

    }

    public class DerivedClass : OverridesAndSecurity,ITestOverrides

    {// Rule violation: The interface has security, and this

    implementation does not.public object GetFormat(Type formatType){

    return (formatType == typeof(OverridesAndSecurity) ?this : null);

    }

    // Rule violation: This does not have security, but thebase class version does.

    public override void DoSomething(){

    Console.WriteLine("Doing some derived thing.");}

    // Rule violation: This has security, but the base classversion does not.

    [EnvironmentPermissionAttribute(SecurityAction.LinkDemand,Unrestricted=true)]

    public override void DoSomethingElse(){

    Console.WriteLine("Doing some other derived thing.");}

    }

    public class DoublyDerivedClass : DerivedClass{

    // The OverridesAndSecurity version of this method does nothave security.

    // Base class DerivedClass's version does.// The DoublyDerivedClass version does not violate the

    rule, but the// DerivedClass version does violate the rule.

    public override void DoSomethingElse(){

    Console.WriteLine("Doing some other derived thing.");}

      Static constructors should be privateA static constructor, also called a class constructor, is used to initialize a type.

    The system calls the static constructor before the first instance of the type is

  • 8/18/2019 C Sharp Coding Guidelines and Best Practices 2

    42/49

    C# Coding Guidelines and Best Practices

    Pradeep Kumar Mishra Page 42

    created or any static members are referenced. The user has no control over

    when the static constructor is called. If a static constructor is not private, itcan be called by code other than the system. Depending on the operations

    performed in the constructor, this can cause unexpected behavior.

    4.6  Interoperability  Do not use AutoDual ClassInterfaceType

    Types that use a dual interface allow clients to bind to a specific interfacelayout. Any changes in a future version to the layout of the type or any base

    types will break COM clients that bind to the interface. By default, if the

    ClassInterfaceAttribute attribute is not specified, a dispatch-only interfaceis used.

    Example:// This violates the rule.

    [ClassInterface(ClassInterfaceType.AutoDual)]

    public class DualInterface{public void SomeMethod() {}

    }

    public interface IExplicitInterface{

    void SomeMethod();}

    [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 memoryso 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, whichwill break COM clients that expect a specific layout. Note that if the

  • 8/18/2019 C Sharp Coding Guidelines and Best Practices 2

    43/49

    C# Coding Guidelines and Best Practices

    Pradeep Kumar Mishra Page 43

    StructLayoutAttribute  attribute is not specified, the C#, Visual Basic, and

    C++ compilers specify the Sequential layout for value types

    Example:// This violates the rule.

    [StructLayout(LayoutKind.Auto)]

    [ComVisible(true)]public struct AutoLayout{

    public int ValueOne;public int ValueTwo;

    }

    // This satisfies the rule.[StructLayout(LayoutKind.Explicit)][ComVisible(true)]public struct ExplicitLayout{

    [FieldOffset(0)]

    public int ValueOne;

    [FieldOffset(4)]public  int ValueTwo;

    }

      Avoid overloads in ComVisible interfaces 

    When overloaded methods are exposed to COM clients, only the first methodoverload retains its name. Subsequent overloads are uniquely renamed by

    appending to the name an underscore character '_' and an integer that

    corresponds to the order of declaration of the overload. For example, considerthe following methods:

    void SomeMethod(int valueOne);

    void SomeMethod(int valueOne, int valueTwo, int valueThree);void SomeMethod(int valueOne, int valueTwo);

    These methods are exposed to COM clients as:

    void SomeMethod(int valueOne);void SomeMethod_2(int valueOne, int valueTwo, int valueThree);void SomeMethod_3(int valueOne, int valueTwo);

    Example:// This interface violates the rule.

    [ComVisible(true)]public interface IOverloadedInterface

    { void SomeMethod(int valueOne);void SomeMethod(int valueOne, int valueTwo);

    }

    // This interface satisfies the rule.[ComVisible(true)]public interface INotOverloadedInterface{

    void SomeMethod(int valueOne);

  • 8/18/2019 C Sharp Coding Guidelines and Best Practices 2

    44/49

    C# Coding Guidelines and Best Practices

    Pradeep Kumar Mishra Page 44

    void AnotherMethod(int valueOne, int valueTwo);}

    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:

      Know when to set up a try/catch block. For example, you can

    programmatically check for a condition that is likely to occur without using

    exception handling. In other situations, using exception handling to catch anerror condition is appropriate.

      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 end-of-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, theexception will take longer to handle.

      Use try/finally blocks around code that can potentially generate an exceptionand 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 centrallocation.

      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 amore general catch block.

      End exception class names with the word "Exception.".

     

    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, supposeApplication Domain A creates Application Domain B, which executes code that

    throws an exception. For Application Domain A to properly catch and handlethe exception, it must be able to find the assembly containing the exception

    thrown by Application Domain B. If Application Domain B throws an exceptionthat 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 aFileNotFoundException. To avoid this situation, you can deploy the assembly

    containing the exception information in two ways:

    Put the assembly into a common application base shared by bothapplication domains, or

    o  If the domains do not share a common application base, sign the

    assembly containing the exception information with a strong name anddeploy the assembly into the global assembly cache.

      In C#, use at least the three common constructors when creating your ownexception classes.

  • 8/18/2019 C Sharp Coding Guidelines and Best Practices 2

    45/49

    C# Coding Guidelines and Best Practices

    Pradeep Kumar Mishra Page 45

    using System;

    public class ListNotFoundException: ApplicationException

    {

    public ListNotFoundException()

    {

    }

    public ListNotFoundException(string message) : base(message)

    {

    }

    public  ListNotFoundException(string  message, Exception inner): base(message, inner) 

    {

    }

      In most cases, use the predefined exceptions types. Define new exceptiontypes 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. Formost 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 user‟s preferred

    language appropriate messages should be shown to the user.

      Use grammatically correct error messages, including ending punctuation.

    Each sentence in a description string of an exception should end in a period.

      Provide Exception properties for programmatic access. Include extra

    information in an exception (in addition to the description string) only when

    there is a programmatic scenario where the additional information is useful.

      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.

      Design classes so that an exception is never thrown in normal use. For

    example, a FileStream class exposes another way of determining whether the

    end of the file has been reached. This avoids the exception that is thrown ifyou read past the end of the file.

      Throw an InvalidOperationException if a property set or method call is notappropriate given the object's current state.

      Throw an ArgumentException or a class derived from ArgumentException ifbad parameters are passed.

  • 8/18/2019 C Sharp Coding Guidelines and Best Practices 2

    46/49

    C# Coding Guidelines and Best Practices

    Pradeep Kumar Mishra Page 46

      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 factwhen deciding where to place a throw statement.

      Use exception builder methods. It is common for a class to throw the sameexception from different places in its implementation. To avoid excessive

    code, use helper methods that create the exception and return it.

      Alternatively, use the exception's constructor to build the exception. This ismore appropriate for global exception classes, such as ArgumentException.

      Throw exceptions instead of returning an error code or HRESULT.

      Clean up intermediate results when throwing an exception. Callers should beable assume that there are no side effects when an exception is thrown from

    a method.

    Additional information about throwing exceptions:

    There is a basic difference between two kinds of exception thrown. So here itshould not only be 'where' but 'what' also.

    For more information please see

    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconbestpracticesforhandlingexceptions.asp 

    The statement

    throw e;

    This will reset the stack trace in exception object "e" so that the stack trace

    begins on the same line as the throw statement. The statement:

    throw;

    This will re-throw the original exception object without resetting the stacktrace. So if you catch an exception, examine and decide you don't really want tohandle it and have nothing of value to add, then simply use

    throw;

    If you want to erase from the stack trace the original line that generated the

    exception (in essence, hide information) then use:

    throw e;

    If you want to add context (this is usually most people do), then use something

    like this:

    throw new Exception("Message",ex);

    This preserves the original exception as the inner exception in the exceptionobject.

    5  Project Settings and Structure

      Always build your project with warning level 4.

    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconbestpracticesforhandlingexceptions.asphttp://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconbestpracticesforhandlingexceptions.asphttp://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconbestpracticesforhandlingexceptions.asphttp://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconbestpracticesforhandlingexceptions.asphttp://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconbestpracticesforhandlingexceptions.asp

  • 8/18/2019 C Sharp Coding Guidelines and Best Practices 2

    47/49

    C# Coding Guidelines and Best Practices

    Pradeep Kumar Mishra Page 47

      Always explicitly state your supported runtime version in the applicationconfiguration file

     

      Populate all fields in AssemblyInfo.cs such as company name, description andcopyright notice. For more information please see any automatically created

    Assemblyinfo.cs file. Following values must be used for the attribute givenbelow… 

    [assembly: AssemblyCompany("Company Inc.")]

    [assembly: AssemblyCopyright("Copyright (c) "+ Year + " Company

    , Inc.")]

    [assembly: AssemblyTrademark("Company")]

    [assembly: AssemblyCulture("")]

    [assembly:CLSCompliant(true)]

  • 8/18/2019 C Sharp Coding Guidelines and Best Practices 2

    48/49

    C# Coding Guidelines and Best Practices

    Pradeep Kumar Mishra Page 48

      Put copyright notice also on the top of every cs file. Following copyright

    information should be used.

    #region  Copyright (c) 2005-2006 Company , Inc. All rightsreserved 

    // **************************************************************// Copyright (c) 2005 Company.

    //

    //The copyright to the computer software herein is proprietary//and remains the property of Company. It may //be used and/orcopied only with the written consent of Company // or inaccordance with the terms and conditions //stipulated in theagreement/contract under which this software //has been supplied.

    // ************************************************************** 

    #endregion 

    Note: You can modify templates in the Visual studio so that each time you add anew 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)

    \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 isby default in Visual Studio)

      Always sign your assemblies, including client applications. For more

    information regarding signing assemblies please see any automatically

    created Assemblyinfo.cs file.

      Make sure there are no cyclic references among assemblies.

    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  

    http://msdn2.microsoft.com/en-us/library/ms229042(en-US,VS.80).aspxhttp://msdn2.microsoft.com/en-us/library/ms229042(en-US,VS.80).aspxhttp://www.gotdotnet.com/Team/FxCop/docs/rules/NamingRules.aspxhttp://www.gotdotnet.com/Team/FxCop/docs/rules/NamingRules.aspxhttp://www.csharpfriends.com/Articles/getArticle.aspx?articleID=336http://www.csharpfriends.com/Articles/getArticle.aspx?articleID=336http://www.tech.purdue.edu/Cpt/Courses/cpt355/C_Sharp_Coding_Standards_and_Guidelines.htmhttp://www.tech.purdue.edu/Cpt/Courses/cpt355/C_Sharp_Coding_Standards_and_Guidelines.htmhttp://www.tech.purdue.edu/Cpt/Courses/cpt355/C_Sharp_Coding_Standards_and_Guidelines.htmhttp://www.tech.purdue.edu/Cpt/Courses/cpt355/C_Sharp_Coding_Standards_and_Guidelines.htmhttp://www.tech.purdue.edu/Cpt/Courses/cpt355/C_Sharp_Coding_Standards_and_Guidelines.htmhttp://www.icsharpcode.net/TechNotes/SharpDevelopCodingStyle03.pdfhttp://www.icsharpcode.net/TechNotes/SharpDevelopCodingStyle03.pdfhttp://www.icsharpcode.net/TechNotes/SharpDevelopCodingStyle03.pdfhttp://www.tech.purdue.edu/Cpt/Courses/cpt355/C_Sharp_Coding_Standards_and_Guidelines.htmhttp://www.tech.purdue.edu/Cpt/Courses/cpt355/C_Sharp_Coding_Standards_and_Guidelines.htmhttp://www.csharpfriends.com/Articles/getArticle.aspx?articleID=336http://www.gotdotnet.com/Team/FxCop/docs/rules/NamingRules.aspxhttp://msdn2.microsoft.com/en-us/library/ms229042(en-US,VS.80).aspx

  • 8/18/2019 C Sharp Coding Guidelines and Best Practices 2

    49/49

    C# Coding Guidelines and Best Practices

    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 variablecontains and what it is intended to be used for. Prefixing a variable with