You are on page 1of 49

C# Coding Guidelines and Best Practices

Dot Net Development Open Book

C# Coding Guidelines and Best Practices

Pradeep Kumar Mishra

Pradeep Kumar Mishra Page 1

C# Coding Guidelines and Best Practices

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

Pradeep Kumar Mishra Page 2

C# Coding Guidelines and Best Practices

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 REFERENCES: ......................................................................................... 48
APPNEDIX A ............................................................................................... 49

Pradeep Kumar Mishra Page 3

C# Coding Guidelines and Best Practices

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. It‟s 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 Naming conventions and style
2.1 Capitalization style
Use 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 that
consist of two or fewer letters. For example: System.IO, System.Web.UI.

Pradeep Kumar Mishra Page 4

whether it's a constant. package. be certain that the names chosen are in compliance with the applicable rules and standards. Expressive names function as an aid to the human reader. a unique name serves only to differentiate one item from another.1.2 Naming rules Naming rules make programs more comprehensible by facilitating them for reading. 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 various elements of the application are named. Let names be long enough meaningfully however short enough avoid being wordy. which can be helpful in understanding the code. which can change. you preserve a layer of abstraction that simplifies the complexity. it makes sense to provide a name that the human reader can comprehend. or class. Programmatically. For example. Pradeep Kumar Mishra Page 5 . for example.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 Rarely used (use a Public Instance Field Pascal Case property instead) Rarely used (use a Protected Instance Field Camel Case property instead) Parameter Camel Case 2. you could use GetNextOrder() instead of GetNextArrayElement(). therefore." By avoiding names that expose the underlying implementation.C# Coding Guidelines and Best Practices 2. They can also give information about the function of the identifier. A tenet of naming is that difficulty in selecting a proper name may indicate that you need to further analyze or define the purpose of an item. However. A name should tell "what" rather than "how.

Where possible. Names may start with an adjective.  Do not use plural tense. make sure the second character is lowercase. since that is the recommended prefix for interface names. So if appropriate naming standards are not defined in this document the FxCop Naming Rules should be used. as in IdentityStore. or noun phrase instead (UserCollection instead of Users)  Do not use any prefix (such as “C”. use System. Xml etc.ProductName.2.1 Namespaces The general rule for namespace naming is: [<Company Name>]. 2.IO not System. use System.Ecommerce.IOs. simple and descriptive words and avoid acronyms and abbreviations unless abbreviation is much more widely used than long form. For example.  Do use sparingly.[<Feature Name>]. avoid starting with the letter “I”.  Do use suffixes at times. 2.  Do consider wider scope modules across an enterprise Example: Company. For example. use a second descriptive noun.  Do avoid the possibility of two published namespaces having the same name.  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).Collections rather than System.2.  Do not use the underscore (“_”).DataLayer.[<SubNameSpace>] Example: Company. There is a widely accepted code analyzer tool called FxCop (See reference section) which also provide some guidelines.[<Product | Technology Name>].  Do use plural namespace names where appropriate.ProductName.Core or Company.  Do not use department or project name as they change too frequently. such as URL. Pradeep Kumar Mishra Page 6 . if your system uses agents then naming something DownloadAgent conveys real information. but should always end with a descriptive noun or noun phrase (User.  Do not have namespaces and classes with the same name. Exceptions to this rule are brand names and abbreviations. for example).Core  Do use whole.Collection. A class should stand on its own. It doesn't matter what it derives from.2 Classes  Do name classes with nouns or noun phrases using Pascal Case. If you must start with that letter. For example. abbreviations in class names. CustomUser or ReadonlyUser).C# Coding Guidelines and Best Practices 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).  Do use Pascal Case and Nouns.

 Do use sparingly. abbreviations in interface names.2.  Do Not use elusive name like Analyze().ProcessInvoice().Process(). // PREFER  Do Use the verb-noun method for naming routines that perform some operation on a given object which describes the operation.3 Method  Do name methods with Pascal Case  Do name methods with active verb forms and imperatives (ProcessInvoice. such as CalculateInvoiceTotal().C# Coding Guidelines and Best Practices  Do not use any underscores. }  Do use suffix „Attribute‟ with custom attribute class. or adjectives describing behavior (what the implementation will be. 2.  Do use similar names when defining a class/interface pair where the class is a standard implementation of the interface. public class NoDataFoundException{ . ICustomAttributeProvider (noun phrase). and IPersistable (adjective).  Do name interfaces with nouns or noun phrases.2.4 Interfaces  Do prefix interface names with the letter “I”. // AVOID! No need to mention “Invoice” in name Invoice. IComponent (descriptive noun). SubmitTransaction).  Do use Pascal Case.  Do not use plural tense (IComponentCollection instead of IComponents)  Do not use any underscores. For example. e. Example: public class InvoiceItemGroup { … } public class Invoice { … } 2.  Do use suffix „Exception‟ with custom exception class.Stream. to indicate that the type is an interface. It is not necessary to include the noun name when the active verb refers directly to the containing class. Example: Invoice.IO.. The names should differ only by the Pradeep Kumar Mishra Page 7 .).g. e.g public class PersistentEntityAttribute  Do add the suffix Stream to types that inherit from System.

Capture. This approach is used for the interface IComponent and its standard implementation. SearchOptions(bitwise flags)  Do define enumerated values using an enum if they are used in a parameter or property. Authorization.  Do use Pascal Case for enum value names.5 Enums  Do use Pascal Case for enums. DefaultBinding. public enum TransactionType { Inquiry. GetProperty. This gives development tools a chance at knowing the possible values for a property or parameter. GetField.C# Coding Guidelines and Best Practices “I” prefix in the interface name. abbreviations in enum names. NonPublic.  Do use a singular name for enums  Do use a plural name for enumerations with bit fields as values also called flags enumerations. Example: public interface IComponent { … } public class Component : IComponent { … } public interface IServiceProvider{ … } public interface IFormatable { … } 2. IgnoreCase.  Do use sparingly. InvokeMethod. OABinding.  Do not use any “Enum” suffix on enum types. Void }  Do use the Flags custom attribute if the numeric values are meant to be bitwise OR-ed together [Flags] public enum Bindings { CreateInstance. Sale. ExcatBinding. SetField Pradeep Kumar Mishra Page 8 .2.  Do not use a family-name prefix on enum. Credit. Component.

Do not use enums for open sets (such as operating system version). or the enum may grow to that many flags in the future. a new overload can be added. If more data is need in the next version.name. (An exception to this rule is if the enum represents flags and there are more than 32 flags. 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. All other variable must follow simply camel Case.  Do use the “this” keyword when referring to members at a class‟s root scope from within a lower level scope.  Do use computation qualifiers (avg.6 Static Fields  Do name static members with nouns. noun phrases.7 Variables  Do use descriptive names such that a variable‟s name that clearly indicates what the purpose of the variable is and what value it will hold.)  Do use enums only if the value can be completely expressed as a set of bit flags.2. which differ from Boolean variables in that they may have more than two possible values. so the parameter name can be put to better use describing semantics rather than type. min. Instead of orderFlag. sum.  Do name static members using Pascal Case. as in this. 2. or isSuccess.2. It is likely that development tools will provide the information about type in a convenient way. A collection of Book objects is named Books.  Do prefix private fields with an underscore (“_”) like _privateField.C# Coding Guidelines and Best Practices SetProperty.  Do initialize variables at the point of declaration if possible. max. or abbreviations for nouns. to names based on the parameter‟s type.  Do not use Hungarian-type prefixes on static member names (Definition of Hungarian notation is given in the Appendix A.  Do name variables using camel case. use a more descriptive name such as orderStatus.  Do name Collections as the plural form of the singular objects that the collection contains.  Do not reserve parameters for future use.  Do not using terms such as Flag when naming status variables. or the type needs to be different from int for backward compatibility. Pradeep Kumar Mishra Page 9 .  Do prefer names based on a parameter‟s meaning. Static }  Do use int as the underlying type of an enum.) 2. such as isFound.

… } } 2. Use single-letter variable names.) Example: public class Person { private int _birthYear.ToString().2. public Person(int birthYear) { this.  Do not use Hungarian-type prefixes.C# Coding Guidelines and Best Practices  Do use a meaningful name even for a short-lived variable that may appear in only a few lines of code. such as i or j for short-loop indexes only. int yearLength = birthYearText. This is the case with all object- oriented languages._birthYear. } set{ this._birthYear = value._birthYear = birthYear. Pradeep Kumar Mishra Page 10 . } public int BirthYear { get{ return this. Instead. such as NUM_DAYS_IN_WEEK.  Do not use all uppercase with underscores between words for constants._birthYear.BookTitle.Title. such as Book. } } public string FormatBirthYear(int totalLength) { string birthYearText = this. The aforementioned constant would be named NumDaysInWeek.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. (Definition of Hungarian notation is given in the Appendix A. use Book. Constants follow the same naming rules as properties.length.

} public class Control { public int Color { get {. } } public int Y { get { return y.9 Events  Do name event handlers with the “EventHandler” suffix.. MouseEvent e). When declaring a property with the same name as a type. For example.x = x.. public class MouseEventArgs : EventArgs { int x..Int32).C# Coding Guidelines and Best Practices  Do consider having a property with the same name as a type.... public delegate void MouseEventHandler(object sender.  Do use two parameters named sender and e. Use an appropriate and specific event class for its type..  Do name event argument classes with the “EventArgs” suffix. MouseEvent e).} } } In the latter case. public delegate void MouseEventHandler(object sender. even if it is possible to employ a more specific type. and this parameter is always of type object.} set {. } } }  Do Consider naming events with a verb.. int y.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.. it will not be possible to refer to the members of the Color enum because Color..} public class Control { public Color Color { get {.2. public MouseEventArgs(int x. Use a gerund (the "ing" form of a verb) to create an event name that expresses the concept of pre-event. } public int X { get { return x. the following is okay public enum Color {. int y) { this. Pradeep Kumar Mishra Page 11 . this. and a past-tense verb to represent post-event.. In other words. also make the type of the property be that type. 2. The state associated with the event is encapsulated in an instance e of an event class. a Close event that can be canceled should have a Closing event and a Closed event.} } } but this is not public enum Color {.} set {.. The sender parameter represents the object that raised the event.y = y.

Cummings. System.NET 2003 or Visual Studio. void F(). Components might need to be usable from both case-sensitive and case-insensitive languages. } 2. #region P R O P E R T I E S public string MyProp. public event ControlEventHandler ControlAdded { //. namespace ee.NET 2005 you can specify code regions. Code regions are basically blocks of code that you can collapse within the Visual Studio IDE. Since case- insensitive languages cannot distinguish between two names within the same context that differ only by case. If you want to provide distinct events for expressing a point of time before and a point of time after a certain occurrence such as a validation event.WinForms. Do not use a pattern like BeginXxx and EndXxx.. use a Validating and Validated pattern. #endregion Pradeep Kumar Mishra Page 12 . System. 2. Examples of what not to do:  Don‟t have two namespaces whose names differ only by case.  Don‟t have a type with two methods whose names differ only by case.2.2.  When using Visual Studio. I typically will group all my properties for a class within a Properties code region. void F(string a. namespace Ee.11 General  Always use „US English‟. For instance.10 Case sensitivity Don‟t use names that require case sensitivity. do not use a pattern like BeforeValidation and AfterValidation.Point p. Instead. void f().C# Coding Guidelines and Best Practices  Do Use an „–ing‟ and „–ed‟ form to express pre-events and postevents.WinForms.POINT p. components must avoid this situation. What code regions enable you to do is group related pieces of code together which makes things easier to find.  Don‟t have a method with two parameters whose names differ only by case.cummings. string A)  Don‟t have a namespace with two types whose names differ only by case.

include a description of the value being returned.  Minimize the use of abbreviations.  Object references should be in camel case and they should be named after their class. public class MyClass { int _number int _name. such as GetCurrentCustomerName(). be consistent in their use.  All member variables should be declared at the top of a class definition. each abbreviated word should have only one abbreviation. always declare a constant instead.C# Coding Guidelines and Best Practices Please note that regions can be nested but they can‟t overlap the other block statements. Pradeep Kumar Mishra Page 13 . do so everywhere and do not later use it to abbreviate minute. in particular type specifications. such as oInvoice. If abbreviations are used.  When naming methods.  Names with semantic content are preferred to names with type specifications (sizeOfArray instead of anInteger). Use the using statement instead.  Avoid using function calls in Boolean conditional statements. public void SomeMethod() }  Implementation details. Assign into local variable and check on them bool ValidateInput() { …. should not be mentioned in the name of a descriptor. if using min to abbreviate minimum. For example. For example InvoiceItemGroup invoiceItemGroup = new InvoiceItemGroup()  With the exception of zero and one. never hard code a numeric value. This approach is not applicable to contemporary languages where the aforementioned identifier is written simply as Invoice. For example Use object and not Object Use string and not String Use int and not Int32  Avoid fully qualified name. An abbreviation should have only one meaning and likewise. This is a common trait in procedural languages like Visual Basic where lowercase prefixes are used to encode the data type in the name of the identifier.  Always use c# predefined types rather than the aliases in the System namespace. Please also note it is NOT ok to satisfy this guideline by defining constants such as FortyTwo = 42.

To create obfuscated code. It is usually bad style to compare a bool-type expression to true or false. meaningless names formed from the letters O.. Example: while (condition == false) // wrong. For example bool b001 = (lo == l0) ? (I1 == 11) : (lOl != 101).. l. use very short. and vice versa. bad style while (condition != true) // also wrong while (((condition == true) == true) == true) // where do you stop? while (booleanCondition) // OK Pradeep Kumar Mishra Page 14 . should not be written  Do not change a loop variable inside a for loop block.. }  Do not use letters that can be mistaken for digits. I and the digits0 and 1.  Do not make explicit comparisons to true or false. } //Correct bool isValidInput = ValidateInput(). even more so if the loop variable is modified in more than one place. if(isValidInput) { .C# Coding Guidelines and Best Practices } //Avoid if(ValidateInput()) { . o. Updating the loop variable within the loop body is generally considered confusing..

Class and interface declarations  Group all framework namespaces together and put custom or third party namespaces underneath.  Break after an operator.Data.Data. Example SomeMethod(longExpresssion1. using Company.3. longExpression3) 3. using Company.) Pradeep Kumar Mishra Page 15 . using statements 2. (By default tab is set to 4 spaces and this will reduce typing.  Prefer higher-level breaks to lower-level breaks.  Consider breaking apart a file as it approaches 1500 lines. 3.  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.ProductName. using System.1 Source Files  Source files should contain one class per source file and name of file should be same as class name.2 Ordering  C# source files have the following ordering: 1.1 Wrapping Lines When an expression will not fit on a single line. For example a file containing class Invoice should have name Invoice. namespace statement 3.cs. 3. Since we use Visual studio as IDE hence it‟s better to use tabs over there.Core.3. using System.ProductName.3 Indentation 3. break it up according to these general principles:  Break after a comma.C# Coding Guidelines and Best Practices 3 Coding Style 3.2 White Spaces Always use 4 spaces for indentation. longExpression2.

00) { grandTotal = grandTotal * 0. 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.  Avoid adding comments at the end of a line of code. Comments should be used to give overviews of code and provide additional information that is not readily available in the code itself. XML documentation is used to indicate the routine's purpose. 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. • Comments should consist of complete sentences and follow active language naming responsibilities (Adds the element instead of The element is added).C# Coding Guidelines and Best Practices 3.4. 3. Doc comments are meant to describe the specification of the code. Use your best judgment to determine an appropriate level of what it means for code to be not really obvious. This point leads to allot of subjective interpretations. A boilerplate comment should be a brief introduction to understand why the routine exists and what it can do. In this case. align all end-line comments at a common tab stop. assumptions.90. 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. end-line comments make code more difficult to read.. if ( grandTotal >= 1000. } Looking at the code in example above one can figure out that a 10% discount is being given on orders of $1. • At the beginning of every routine.  Throughout the application.1 Implementation Comments  Block Comments Pradeep Kumar Mishra Page 16 .4 Comments C# programs can have two kinds of comments: implementation comments and documentation comments. and //.*/. to be read by developers who might not necessarily have the source code at hand. construct comments using a uniform style. end-line comments are appropriate when annotating variable declarations. from an implementation-free perspective. always keep the commenting around it up to date.. and limitations. with consistent punctuation and structure. Following are recommended commenting techniques:  When modifying code.000 dollars or more. Implementation comments are those found in C++. Documentation comments are C# only.  Comment anything that is not readily obvious in the code. However. which are delimited by /*. Consider an example below.

} else { return false. Code Reviewer should check this. Code-disabling comment delimiters are found in the first position of a line of code flush with the left margin.  Single-Line Comments Short comments can appear on a single line indented to the level of the code that follows.. . // Explain why here. CTRL+C. To uncomment. such as within methods. If a comment can't be written in a single line. Block comments inside a function or method should be indented to the same level as the code they describe. }  Trailing Comments Very short comments can appear on the same line as the code they describe. A blank line to set it apart from the rest of the code should precede a block comment.(Unless there is very specific reason. We should try not to check in the commented code as that may confuse other developers working on the same code.) The following is an example of code-disabling comments: if (foo > 1) { // Do a double-flip.. They can also be used in other places. but should be shifted far enough to separate them from the statements.NET provides for bulk commenting by selecting the lines of code to disable and pressing CTRL+K. A single-line comment should be preceded by a blank line. methods. CTRL+U chord. //add the three scores into the sum a = float(ss) / x. } // if (bar > 1) Pradeep Kumar Mishra Page 17 . . use the CTRL+K.. they should all be indented to the same tab setting. // Here is a block comment // that breaks across multiple // lines. data structures and algorithms. Block comments may be used at the beginning of each file. if (condition) { // Handle the condition.C# Coding Guidelines and Best Practices Block comments are used to provide descriptions of files. If more than one short comment appears in a chunk of code.. //calculate the mean of the scores  Code-Disabling Comments The // comment delimiter can comment out a complete line or only a partial line. Here's an example of a single-line comment in code. Visual Studio . Here's an example of a trailing comment in C# code: ss = s1 + s2 + s3. it should follow the block comment format.

variable. The compiler will verify that this code element exists. interface. .  There is a recommended set of tags..  Developers are not free to create their own set of tags.XML markup are not displayed in the Task List. Document comments must not be positioned inside a method or constructor definition block.. o The cref attribute can be attached to any tag to provide a reference to a code element. // . the compiler issues a warning. and . o The <summary> tag is used by IntelliSense inside Visual Studio to display additional information about a type or member. a warning is generated and the documentation file will contain a comment saying that an error was encountered. 3.2 Documentation Comments C# provides a mechanism for developers to document their code using XML.3 Comment Tokens When you add comments with comment tokens to your code. Pradeep Kumar Mishra Page 18 . you automatically add shortcuts to the Task List window.  Some of the recommended tags have special meanings: o The <param> tag is used to describe parameters. The compiler also respects any using statements when looking for a type described in the cref attribute.4. the compiler issues a warning.CSS. If you need to give information about a class. If the XML is not well-formed. If the verification failed.C# Coding Guidelines and Best Practices // { // // // Do a triple-flip. XML documentation starts with ///.4. because C# associates documentation comments with the first declaration after the comment. Double-click any comment displayed in the Task List to move the insertion point directly to the line of code where the comment begins. Note: Comments in HTML. the compiler will verify that the parameter exists and that all parameters are described in the documentation. // } // else // { // return false. or method that isn't appropriate for documentation. If the verification failed. If used. Consider following points while writing XML documentation…  The documentation must be well-formed XML. use an implementation block comment or single-line comment immediately after the declaration. // } 3.

 The closing brace " }" starts a line by itself indented to match its corresponding opening brace. string name = myObject. HACK.. } 3. int level. or UNDONE. or int val = time. the following formatting rules should be followed:  No space between a method name and the parenthesis "(" starting its parameter list.3 Class and Interface Declarations When coding C# classes and interfaces..Hours.  The opening brace "{" appears in the next line after the declaration statement. Add the Comment text. int size.5 Formatting Visual studio 2005 has an auto formatting feature and overall we should follow its style and rules. Pradeep Kumar Mishra Page 19 .6. // ToDo: Fix this later // Hack: Temporary solution to be enhanced later 3. Enter TODO.6.C# Coding Guidelines and Best Practices To add a comment hyperlink to the Task List window.6 Declaration 3. 3. In other words. enter the comment marker. Note: If you initialize a dialog try to use the using statement: using (OpenFileDialog openFileDialog = new OpenFileDialog()) { .6. 3.2 Initialization Try to initialize local variables as soon as they are declared. Do not put more than one variable or variables of different types on the same line when declaring them.1 Number of Declarations per Line One declaration per line is recommended since it encourages commenting1.Name.

} void Inc() { ++myInt.C# Coding Guidelines and Best Practices This is the formatting followed by VS2005 auto formatter. if-else and if else-if else statements should look like this: if (condition) { DoSomething().7 Statements 3.1 Simple Statements Each line should contain only one statement. Don't use : return (n * (n + 1) / 2). For example : class MySample : MyClass. .3 If. public MySample(int myInt) { this. use : return n * (n + 1) / 2. 3. if else-if else Statements if. if-else.7. } if (condition) Pradeep Kumar Mishra Page 20 .7.myInt = myInt . } void EmptyMethod() { } } 3.2 Return Statements A return statement should not use outer most parentheses. IMyInterface { int myInt..7.. 3.

} else { DoSomethingOther(). } Pradeep Kumar Mishra Page 21 .. . } 3..g... . . } else if (condition) { DoSomethingOther(). } else { DoSomethingOtherAgain().. E. if(connection!=null) { Connection.. ++i) { ...C# Coding Guidelines and Best Practices { DoSomething()..4 For / Foreach Statements A for statement should have following form: for (int i = 0... .7. i < 5.. } Note: Always use brackets even if there is only one statement in the loop.close(). . } if (condition) { DoSomething().

. 3.. break...C# Coding Guidelines and Best Practices A foreach should look like : foreach (int i in IntList) { . A do-while statement should have the following form: do { ... A switch statement should be of following form switch (condition) { case A: . break. break.... default: .6 Switch Statements Always use default case with switch statement.7. case B: .5 While/do-while Statements A while statement should be written as follows: while (condition) { . } 3. Pradeep Kumar Mishra Page 22 . } while (condition)..7. } An empty while should have the following form: while (condition) ...

gotdotnet. Most of the content of this section has been taken as it is from http://www. Security. Globalization. Interoperability and Exceptions..com and FxCop (http://www. Design.. } catch (Exception e) { ... } 4 Best Practices This section discuss about the best practices that should be followed while writing code in c#.... Usage. } catch (Exception e) { } or try { . The section is divided in subsection based on Performance.7.7 Try-catch Statements A try-catch statement should follow this form: try { .C# Coding Guidelines and Best Practices } 3. Pradeep Kumar Mishra Page 23 .codeproject. } finally { .com/team/fxcop/) rules..

arrayOfStrings. } For very simple concatenation we should directly add them as follows: //Yes return a + b + c. }  Prefer StringBuilder instead of string concatenation.. foreach (string s in stringContainer) { strConcat += s. cannot be altered. } //YES if ( str. //NO StringBuilder a = new StringBuilder(). use the Length property. When you alter a string. you are actually creating a new string causing the following:  The code uses more memory than necessary.Add("b"). you should prefer using StringBuilder (Append method). Code snippets: //NO string strConcat.  Creates more work for the garbage collector. arrayOfStrings.Add("a"). foreach (string s in arrayOfStrings ) { sbConcat. C# string is immutable. ArrayList arrayOfStrings = new ArrayList().Length > 0) { .. i.C# Coding Guidelines and Best Practices 4...1 Performance  Prefer the Length property when checking string size String comparison involves unnecessary overhead. If all you need is to check whether the string is empty.  Makes the code execution run slower.e. Pradeep Kumar Mishra Page 24 .append(s).. } //YES StringBuilder sbConcat = new StringBuilder (). Therefore. Code snippets: //NO if ( str != “”)//comparison of two strings { .

By default. Allocating an object instance.NET Framework class library provides methods for retrieving custom attributes. do not declare your data type as struct (Value type) because ArrayList works with Object (Reference type) and every time you add an instance of the struct or run over the container.C# Coding Guidelines and Best Practices a. or any attribute type that extends the specified attribute type. for example.GetCustomAttribute searches for the specified attribute type. } public string Name { get { return nameValue. The . in a loop. Given the above.  Avoid unsealed attributes. The following happens when you copy one of the collection items value into the struct: Pradeep Kumar Mishra Page 25 . Boxing a value of a value-type consists of two operations: 1.Append(b). [AttributeUsage(AttributeTargets. return a. a. for example System. you should avoid Boxing as much as you can. and can improve performance.Class|AttributeTargets. a Boxing process will occur.Append(c).Struct)] public sealed class DeveloperAttribute: Attribute { private string nameValue.Attribute. 2. public DeveloperAttribute(string name) { nameValue = name. these methods search the attribute inheritance hierarchy. Copying the value-type value into that instance. If you intend to work with ArrayList. Sealing the attribute eliminates the search through the inheritance hierarchy. Example: using System. } } } }  Avoid Boxing and UnBoxing as much as possible. namespace PerformanceLibrary { //AvoidUnsealedAttributes.

for (int i=0 . //<... use the Equal method.Boxing (Allocating an object instance // + copying the value-type value into that instance) } st obj = (st ) arr[0]. Pradeep Kumar Mishra Page 26 . s. Note: Collections expect object type.Equals(s2)) { . } //Yes: if(s1.item.i = 4. Code snippets: string s1= "code". //No: if(s1 == s2) { . Code snippets: //NO struct st { public Int i. i< count. }  Use Native Image Generator (nGen.Equal method instead of == operator.add(st) .C# Coding Guidelines and Best Practices  Casting. Using the string.. i++) { st s.. string s2 = "code1". arr. //<.  Copy the value.Unboxing (casting and copy) //YES //Decalre the data type as class. So if you are very keen and need special type of performance and expect that most of the strings will be the same.Equals method is much faster when the strings are matched. Class st { public int i.exe) in case of long and heavy initialization. }  Prefer String. Note: The differences in performance are negligible and effect only numerous operations. } Arraylist arr = new ArrayList().

Length. only under the hood the foreach hurts the performance. You do not have to perform any additional procedures to cause the runtime to use a native image. using: ngen [options] [assemblyName |assemblyPath ]  Prefer 'for' over 'foreach'. because you can call the nGen command on the installation machine through your project setup. Moreover.exe on an assembly allows the assembly to load and execute faster. Running Ngen. "The nGen creates a native image from a managed assembly and installs it into the native image cache on the local computer." (MSDN 2005) You do not have to lose the advantage of JIT compilation. foreach(int i arrayOfInts) { sum+= i. In case of heavy and long initialization in your assembly.NET Framework runs C# assemblies using the JIT compiler. we can see that both loop blocks produce the same results.run in loop over block of statements. More variables are involved and additional heavy array copy.NET tool. int sum= 0. i < arrayOfInts. Code snippets: //foreach int[] arrayOfInts= new int[5]. } //for int[] arrayOfInts= new int[1]. Once you create a native image for an assembly. 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. int sum= 0. for(int i = 0. you might want to use the nGen . Pradeep Kumar Mishra Page 27 . i++) { sum+= arrayOfInts[i]. One can say that foreach is a private case of for. The foreach is far handier to use especially for collections but if your code runs over large collections. the runtime automatically uses that native image each time it runs the assembly. In the code snippets below. the foreach statement is designed to traverse through the entire collection. Each code that is executed for the first time is being compiled. 'foreach' and 'for' statements serve the same goal . prefer using 'for'.C# Coding Guidelines and Best Practices The . because it restores code and data structures from the native image cache rather than generating them dynamically.

if(obj is Control) { // The 'as' statement performs a duplicate cast operation. if(aControl != null) { // Use aControl. Control aControl = obj as Control. consider testing the result of the as operator instead. public static void UnderPerforming(ArrayList list) { foreach(object obj in list) { // The 'is' statement performs a cast operation. especially when the casts are performed in compact iteration statements.2 Usage  Use string. If the C# is operator is used to test whether the cast will succeed before the actual cast is performed. store the result of the cast in a local variable and use the local variable instead of the duplicate cast operations. } } } } } 4. public static void BetterPerforming(ArrayList list) { foreach(object obj in list) { Control aControl = obj as Control. Example: namespace PerformanceLibrary { public sealed class SomeClass { private SomeClass() {} // NO. } } } // Yes.Empty instead of “” Pradeep Kumar Mishra Page 28 . // Use aControl. For explicit duplicate cast operations. This provides the same functionality without the implicit cast operation performed by the is operator.C# Coding Guidelines and Best Practices }  Do not cast unnecessarily. Duplicate casts degrade performance.

// problem after statment excution // the shortNum variable has an uninitialized value. Code snippets: //interface definition public interface IChild{ bool IsHuman(). //YES try { shortNum = checked((short)i). Code snippets: //NO short shortNum. ((IChild) o). shortNum = (short) i.C# Coding Guidelines and Best Practices //Avoid string name = “”. Pinocchio o = new Pinocchio(). }  Collection properties should be read only.Empty.Lie().IsHuman(). // using the IsHuman method explicitly. // solution } catch(OverflowException efx) {}  Use Explicit interface to 'hide' the implementation of an interface Implementing an interface explicitly 'hides' the interface methods. } //class definition public Pinocchio: IChild { IChild.IsHuman() //explicit interface implementation { } public void Lie(). int i = 32768. Pradeep Kumar Mishra Page 29 . o.  Use the 'checked' keyword to avoid overflow. Visual Studio does not display the interface methods in the intellisense. void lie(). //regular interface implementation } //using the object static void main() { // Visual studio will not display // the isHuman mwthod in the intellisence. //Correct string name = string.

"new". "IList"} ).Clear(). } // Violates the rule. "ICollection". Example: The following example shows a type with a writable collection property and shows how the collection can be replaced directly. } } public WritableCollection() { strings = new ArrayList( new string[] {"IEnumerable". collection. A read-only property stops the collection from being replaced while still allowing the individual members to be set. the preferred design pattern is to include a method to remove all the elements from the collection and a method to re- populate the collection. public ArrayList SomeStrings { get { return strings. WritableCollection collection = new WritableCollection().AddRange(newCollection). "collection"} ).C# Coding Guidelines and Best Practices A writable collection property allows a user to replace the collection with an entirely different collection. If replacing the collection is a goal. } } class ReplaceWritableCollection { static void Main() { ArrayList newCollection = new ArrayList( new string[] {"a". // strings is directly replaced with newCollection.SomeStrings.SomeStrings. collection. set { strings = value. } } } Pradeep Kumar Mishra Page 30 . In addition. namespace UsageLibrary { public class WritableCollection { ArrayList strings. // newCollection is added to the cleared strings collection.SomeStrings = newCollection. the preferred manner of replacing a read-only collection property using Clear and AddRange methods is shown. collection.

Note 2: If you implement the IDisposable and a destructor..exe). Code snippets: using System. Prefer to define the attribute for the entire assembly. you create unnecessary work for the garbage collector.txt”.C# Coding Guidelines and Best Practices  Use @ to ease the work with literal paths. use types that are not managed by the garbage collector. The incentive to create a CLS compliant assembly is that any assembly written in one of the . But. You should define a destructor whenever you use native code in your assembly.txt”. This behavior guarantees that your release of resources in the destructor will occur. Code snippets: ~my class { if ( true == b) { } } //The MSIL code: protected override void Finalize() { try { Pradeep Kumar Mishra Page 31 . //The C# way string sFilePath = @”c:\a\b\c. what if you want to release the resources immediately? For this purpose. you should call the Dispose method from the destructor to force the object to release resources immediately. The CLS-Compliant attribute cause the compiler to check whether your public exposed types in the assembly are CLS-Compliant. [assembly:CLSCompliant(true)]  Define destructor and implement IDisposable interface for classes that use native resource directly. If you do so.NET aware languages can use your assembly more efficiently because there is no data type interoperability. you should implement the IDisposable interface and call the Dispose method when you want to release the object. i.e. especially for API. The compiler changes the destructor method to Finalize method (can be seen in the MSIL using the ILDasm. Code snippets: //Old way string sFilePath = “c:\\a\\b\\c. Note 1: Do not use destructor if your class does not use native / unmanaged resources.  Make your API assembly CLS Compliant. The Garbage collector marks a class with destructor as Finalized and calls the Finalize method while destructing the object.

If you must use it in order to reclaim the maximum amount of available memory. those object live longer than it should in the first place. The performance is hurt during the call to GC. Moreover. Because public constructors create instances of a type. i. 4.Collect. public BadAbstractClassWithConstructor() { // Add constructor logic here.Collect method forces garbage collection of all generations. Example: namespace DesignLibrary { public abstract class BadAbstractClassWithConstructor { //WRONG: AbstractTypesShouldNotHaveConstructors. use the method only on generation 0..C# Coding Guidelines and Best Practices if ( true == b) { } } finally { base.Collect(0). any type derived from the base type can be passed as the corresponding argument to the Pradeep Kumar Mishra Page 32 . //Yes: GC.Finalize().} }  Avoid the use of GC. When a base type is specified as a parameter in a method declaration.3 Design  Abstract type should not have public constructors Constructors on abstract types can only be called by derived types. the method might cause the promotion of short lived objects to a higher generation. an abstract type with a public constructor is incorrectly designed.e.Collect. } } }  Consider passing base types as parameters.Collect(). Code snippets: //No: GO. the application execution is paused. } } public abstract class GoodAbstractClassWithConstructor { protected GoodAbstractClassWithConstructor() { // Add constructor logic here. The GC. and you cannot create instances of an abstract type.

like other value types.ManipulateFileStream(testFileStream). assign zero to the most commonly used member. its value is zero by default.ManipulateAnyStream(testMemoryStream). is zero.ManipulateAnyStream(testFileStream). } } public void ManipulateAnyStream(Stream anyStream) { while((anInteger = anyStream. someStreamUser. MemoryStream testMemoryStream = new MemoryStream(new byte[] {}). Note that if the value of the first enumeration member is not set in the declaration. 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. the specific method that is executed depends on the type of the argument.dat".ReadByte()) != -1) { // Do something. someStreamUser. If appropriate. name the member 'None'. Pradeep Kumar Mishra Page 33 . using(FileStream testFileStream = new FileStream("test. public void ManipulateFileStream(FileStream stream) { while((anInteger = stream.C# Coding Guidelines and Best Practices method. FileMode. someStreamUser. Example: namespace DesignLibrary { public class StreamUser { int anInteger. use of the base type allows the method to be more widely utilized. } } } class TestStreams { static void Main() { StreamUser someStreamUser = new StreamUser(). } } } }  Enums should have zero value The default value of an un-initialized enumeration. Otherwise. If the additional functionality provided by the derived type is not required. When the argument is used inside the method body.OpenOrCreate)) { // Cannot be used with testMemoryStream.ReadByte()) != -1) { // Do something.

Example: public enum TraceLevel { Off = 0. This implies that only one member should be assigned the value zero. Timestamp = 0x04. 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 are useless with the member. Info = 3. Pradeep Kumar Mishra Page 34 . Error = 1. Timestamp = 0x08. Verbose = 4 } //Correct [Flags] public enum TraceOptions { None = 0. } //Wrong [Flags] public enum BadTraceOptions { CallStack = 0. Enum. DateTime = 0x02.C# Coding Guidelines and Best Practices If an enumeration that has the FlagsAttribute applied defines a zero-valued member. CallStack = 0x01.ToString() returns incorrect results for members that are not zero. }  Mark assemblies with ComVisible. DateTime = 0x04. LogicalStack = 0x01. Warning = 2. Note that if there are multiple members with the value zero in a flags-attributed enumeration. LogicalStack = 0x02. its name should be 'None' to indicate that no values have been set in the enumeration.

} } }  Do not use string as type for URI parameters/properties or URI return values. and then preventing the user from viewing the value does not provide any security. the contents of the assembly are visible to COM clients. While it is acceptable and often necessary to have a read-only property. a corresponding overload should be provided that Pradeep Kumar Mishra Page 35 . the design guidelines prohibit the use of write-only properties because allowing a user to set a value. public string Name { get { return someName. } } } public class GoodClassWithReadWriteProperty { string someName. and can lead to security vulnerabilities. public string Name { set { someName = value. } set { someName = value. Good design dictates that assemblies explicitly indicate COM visibility. Also. which limits their usefulness. // Violates rule PropertiesShouldNotBeWriteOnly. COM visibility can be set for an entire assembly and then overridden for individual types and type members. the state of shared objects cannot be viewed. Get accessors provide read access to a property and set accessors provide write access. If a method takes a string representation of a URI. without read access. Example: public class BadClassWithWriteOnlyProperty { string someName. [assembly: ComVisible(false)] //can be true or false  Properties should not be write only. If the attribute is not present.C# Coding Guidelines and Best Practices The ComVisibleAttribute attribute determines how COM clients access managed code. A string representation of a URI is prone to parsing and encoding errors.

// To retrieve a string.ToString(). } set { someUri = value. // To set using a string. public void AddToHistory(string uriString) { } // Violates rule UriReturnValuesShouldNotBeStrings. call SomeUri. } Pradeep Kumar Mishra Page 36 . which provides these services in a safe and secure manner. } } public class SaferWay { Uri someUri. // Violates rule UriPropertiesShouldNotBeStrings. Example: namespace DesignLibrary { public class ErrorProne { string someUri.adventure-works. public string GetRefererUri(string httpHeader) { return "http://www. public Uri SomeUri { get { return someUri. public string SomeUri { get { return someUri.C# Coding Guidelines and Best Practices takes an instance of the Uri class. } set { someUri = value. call SomeUri = new Uri(string). } } // Violates rule UriParametersShouldNotBeStrings.com".

CommonApplicationData)). // Do Not.WriteLine(Environment. } } } 4. Example: namespace GlobalizationLibrary { class WriteSpecialFolders { static void Main() { string string0 = "C:". Pradeep Kumar Mishra Page 37 . AddToHistory(new Uri(uriString)). Console.adventure-works. } } }  Do pass IFormat provider and CultureInfo. string string1 = @"\Documents and Settings".SpecialFolder.4 Globalization  Do not hardcode locale specific strings. } public void AddToHistory(Uri uriType) { } public Uri GetRefererUri(string httpHeader) { return new Uri("http://www.C# Coding Guidelines and Best Practices } public void AddToHistory(string uriString) { // Check for UriFormatException. string string2 = @"\All Users". // Do use Console.WriteLine(string0 + string1 + string2 + string3).com").GetFolderPath( Environment. string string3 = @"\Application Data".

Code that makes decisions or performs operations based on the elements of a publicly accessible read-only array might contain an exploitable security vulnerability. you should supply culture-specific information Example: namespace GlobalLibGlobalLibrary { public class IFormatProviderTest { public static void Main() { string dt = "6/4/1900 12:15:12".Parse(dt). however. Example: public class MyClassWithReadOnlyArrayField { Pradeep Kumar Mishra Page 38 .CurrentThread.Parse is to use // the current culture. //This gives out put as 06/04/1900 12:15:12 } } } 4.WriteLine(myDateTime). // and parsing the same string yields a different value.C# Coding Guidelines and Best Practices When a CultureInfo or System. Console. the default value supplied by the overloaded member might not have the effect that you want in all locales.Parse(dt). true). Also.WriteLine(myDateTime). DateTime myDateTime = DateTime. myDateTime = DateTime. .CurrentCulture = new CultureInfo("Fr-fr".NET Framework members choose default culture and formatting based on assumptions that might not be correct for your code. Thread. To ensure the code works as expected for your scenarios. // Here IFormatProvider has not been specified.IFormatProvider object is not supplied.g French). //This gives out put as 6/4/1900 12:15:12 PM // Change the current culture to the required culture (e. the field cannot be changed to refer to a different array. // The default behavior of DateTime. the elements of the array stored in a read-only field can be changed. Console.5 Security  Array fields should not be read only When you apply the readonly modifier to a field that contains an array.

90}. An internal interface creates a contract that is not intended to be implemented outside the assembly that defines the interface. instead. which cannot be changed by the implementing type. If a second type in the defining assembly calls the method and expects an internal-only contract. 90. but is still vulnerable because it is returned to callers by the GetPrivateGrades method. the overridden method in the outside assembly is executed. In this example. } }  Asserts require security demands Asserting security permission without performing any security checks can leave an exploitable security weakness in your code SecurityPermission securePermission = new SecurityPermission(PermissionState.Unrestricted). and therefore vulnerable to any caller. all callers are required to have all security permissions before permission to access environment variables is asserted.C# Coding Guidelines and Best Practices // The field grades is public. A public type 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. a SecurityException is thrown. public readonly int[] grades = {90. public int[] GetPrivateGrades() { return privateGrades. // Making the array private does not protect it because it is passed to others. /*Demand some permission(s) that all callers must have before you will assert permission on their behalf. 90.Demand(). 90. 90}. // Internal by default. interface IValidate { bool UserIsValidated(). //If the demand fails. */ securePermission.  Public types that implement non-public interfaces should be sealed Interface methods have public accessibility. 90}. private readonly int[] privateGrades = {90. private readonly int[] securePrivateGrades = {90. } Pradeep Kumar Mishra Page 39 . This creates security vulnerability. behavior might be compromised when. // The field privateGrades is private.

Example: public interface ITestOverrides { [EnvironmentPermissionAttribute(SecurityAction. } } }  Virtual methods and their Overrides require the same Link Demand status. and has the security status."). Unrestricted=true)] public virtual void DoSomething() Pradeep Kumar Mishra Page 40 . } // These two methods are overridden by DerivedClass and DoublyDerivedClass.GetFormat(Type formatType) { return (formatType == typeof(OverridesAndSecurity) ? this : null). so should any override of it.").WriteLine("Please login. and this implementation does not. [EnvironmentPermissionAttribute(SecurityAction. then immediate overriding of that member should also have the same security status. and if an Override has a Link Demand.LinkDemand. If a virtual method has a Link Demand. } else { Console. so should the overridden virtual method Ex: If a method in the base class is declared as virtual.WriteLine("Account number & balance. Unrestricted=true)] Object GetFormat(Type formatType).LinkDemand.C# Coding Guidelines and Best Practices public class BaseImplementation : IValidate { public virtual bool UserIsValidated() { return false. } public class OverridesAndSecurity : ITestOverrides { // Rule violation: The interface has security.UserIsValidated() == true) { Console. object ITestOverrides. } } public class UseBaseImplementation { public void SecurityDecision(BaseImplementation someImplementation) { if(someImplementation.

and this implementation does not. public object GetFormat(Type formatType) { return (formatType == typeof(OverridesAndSecurity) ? this : null). } } public class DerivedClass : OverridesAndSecurity. [EnvironmentPermissionAttribute(SecurityAction. is used to initialize a type. The system calls the static constructor before the first instance of the type is Pradeep Kumar Mishra Page 41 . Unrestricted=true)] public override void DoSomethingElse() { Console.WriteLine("Doing some other derived thing."). // Base class DerivedClass's version does. } }  Static constructors should be private A static constructor. also called a class constructor.WriteLine("Doing some other thing."). // The DoublyDerivedClass version does not violate the rule.").").WriteLine("Doing some other derived thing. } } public class DoublyDerivedClass : DerivedClass { // The OverridesAndSecurity version of this method does not have security.C# Coding Guidelines and Best Practices { Console.WriteLine("Doing some derived thing. public override void DoSomethingElse() { Console. } // Rule violation: This has security. ITestOverrides { // Rule violation: The interface has security. but the base class version does. but the // DerivedClass version does violate the rule."). public override void DoSomething() { Console.LinkDemand. } public virtual void DoSomethingElse() { Console. } // Rule violation: This does not have security. but the base class version does not.WriteLine("Doing something.

[StructLayout(LayoutKind. it can be called by code other than the system. }  Auto layout types should not be ComVisible Auto layout types are managed by the common language runtime. 4. The layout of these types can change between versions of the . The user has no control over when the static constructor is called. 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. 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). this can cause unexpected behavior. float f.Runtime.C# Coding Guidelines and Best Practices created or any static members are referenced.AutoDual)] public class DualInterface { public void SomeMethod() {} } public interface IExplicitInterface { void SomeMethod(). Depending on the operations performed in the constructor. Example: // This violates the rule. Code snippets: using System. which will break COM clients that expect a specific layout. If a static constructor is not private. By default.Sequential)] public struct st { int i.NET Framework.InteropServices. } [ClassInterface(ClassInterfaceType.6 Interoperability  Do not use AutoDual ClassInterfaceType Types that use a dual interface allow clients to bind to a specific interface layout. Note that if the Pradeep Kumar Mishra Page 42 . a dispatch-only interface is used.None)] public class ExplicitInterface : IExplicitInterface { public void SomeMethod() {} }  Use StructLayout attribute for classes and structs when using COM Interop. [ClassInterface(ClassInterfaceType. if the ClassInterfaceAttribute attribute is not specified.

[StructLayout(LayoutKind. int valueThree). void SomeMethod(int valueOne. int valueThree). public int ValueTwo. int valueTwo. Visual Basic. For example. the C#. void SomeMethod_3(int valueOne. and C++ compilers specify the Sequential layout for value types Example: // This violates the rule.C# Coding Guidelines and Best Practices StructLayoutAttribute attribute is not specified. [ComVisible(true)] public interface IOverloadedInterface { void SomeMethod(int valueOne). int valueTwo). }  Avoid overloads in ComVisible interfaces When overloaded methods are exposed to COM clients. [FieldOffset(4)] public int ValueTwo. Example: // This interface violates the rule. void SomeMethod(int valueOne. int valueTwo).Explicit)] [ComVisible(true)] public struct ExplicitLayout { [FieldOffset(0)] public int ValueOne.Auto)] [ComVisible(true)] public struct AutoLayout { public int ValueOne. int valueTwo). int valueTwo. [ComVisible(true)] public interface INotOverloadedInterface { void SomeMethod(int valueOne). These methods are exposed to COM clients as: void SomeMethod(int valueOne). consider the following methods: void SomeMethod(int valueOne). only the first method overload retains its name. void SomeMethod(int valueOne. [StructLayout(LayoutKind. } // This interface satisfies the rule. Pradeep Kumar Mishra Page 43 . void SomeMethod_2(int valueOne. 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. } // This satisfies the rule.

you can programmatically check for a condition that is likely to occur without using exception handling. using exception handling is better because less code is executed in the normal case. it must be able to find the assembly containing the exception thrown by Application Domain B. use at least the three common constructors when creating your own exception classes.  In C#. This technique handles the specific exception before it is passed to a more general catch block. In this way. and the catch statement handles the exception from a central location. the exception will take longer to handle. For Application Domain A to properly catch and handle the exception. using the programmatic method to check for errors is better. the try statement generates the exception.  The method you choose depends on how often you expect the event to occur. suppose Application Domain A creates Application Domain B.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. To avoid this situation. Application Domain A will not be able to find the exception and the common language runtime will throw a FileNotFoundException. For example. using exception handling to catch an error condition is appropriate. If the event is truly exceptional and is an error (such as an unexpected end- of-file). including when exceptions occur across application domains. if an exception occurs. The following list contains suggestions on best practices for handling exceptions:  Know when to set up a try/catch block. int valueTwo). If the event happens routinely. or o If the domains do not share a common application base.  Always order exceptions in catch blocks from the most specific to the least specific. In this case. sign the assembly containing the exception information with a strong name and deploy the assembly into the global assembly cache. If Application Domain B throws an exception that is contained in an assembly under its application base. you must ensure that the metadata for the exceptions is available to code executing remotely.C# Coding Guidelines and Best Practices void AnotherMethod(int valueOne. you can deploy the assembly containing the exception information in two ways: o Put the assembly into a common application base shared by both application domains. } 4. Pradeep Kumar Mishra Page 44 . but not under Application Domain A's application base. the finally statement closes or deallocates resources. which executes code that throws an exception.  When creating user-defined exceptions.".  Use try/finally blocks around code that can potentially generate an exception and centralize your catch statements in one location. For example. In other situations.  End exception class names with the word "Exception.

the exception code should be returned and then based on user‟s preferred language appropriate messages should be shown to the user. a FileStream class exposes another way of determining whether the end of the file has been reached. inner) { } }  In most cases.C# Coding Guidelines and Best Practices using System. File.  Return null for extremely common error cases.  Use grammatically correct error messages. Introduce a new exception class to enable a programmer to take a different action in code based on the exception class.  Throw an InvalidOperationException if a property set or method call is not appropriate given the object's current state. derive custom exceptions from the Application Exception class. Define new exception types only for programmatic scenarios. use the predefined exceptions types. but throws an exception if the file is locked.  Design classes so that an exception is never thrown in normal use.  Do not derive user-defined exceptions from the Exception base class. For example. in case error occurs . Each sentence in a description string of an exception should end in a period. For most applications. 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. public class ListNotFoundException: ApplicationException { public ListNotFoundException() { } public ListNotFoundException(string message) : base(message) { } public ListNotFoundException(string message.  Throw an ArgumentException or a class derived from ArgumentException if bad parameters are passed. Exception inner) : base(message.  Instead of sending error messages directly to the user.  Provide Exception properties for programmatic access.Open returns null if the file is not found. including ending punctuation. Pradeep Kumar Mishra Page 45 . For example. This avoids the exception that is thrown if you read past the end of the file.

ex). examine and decide you don't really want to handle it and have nothing of value to add.  Throw exceptions instead of returning an error code or HRESULT.  Use exception builder methods. 5 Project Settings and Structure  Always build your project with warning level 4.microsoft. This will reset the stack trace in exception object "e" so that the stack trace begins on the same line as the throw statement. If you want to add context (this is usually most people do). Additional information about throwing exceptions: There is a basic difference between two kinds of exception thrown. hide information) then use: throw e. So here it should not only be 'where' but 'what' also. This will re-throw the original exception object without resetting the stack trace. Pradeep Kumar Mishra Page 46 . The statement: throw. Callers should be able assume that there are no side effects when an exception is thrown from a method. It is common for a class to throw the same exception from different places in its implementation.asp?url=/library/en- us/cpguide/html/cpconbestpracticesforhandlingexceptions. To avoid excessive code. use the exception's constructor to build the exception.asp The statement throw e. Be aware of this fact when deciding where to place a throw statement. such as ArgumentException.  Clean up intermediate results when throwing an exception.C# Coding Guidelines and Best Practices  The stack trace begins at the statement where the exception is thrown and ends at the catch statement that catches the exception.com/library/default. This is more appropriate for global exception classes. So if you catch an exception. then simply use throw. If you want to erase from the stack trace the original line that generated the exception (in essence.  Alternatively. then use something like this: throw new Exception("Message". For more information please see http://msdn. This preserves the original exception as the inner exception in the exception object. use helper methods that create the exception and return it.

Following values must be used for the attribute given below… [assembly: AssemblyCompany("Company Inc.C# Coding Guidelines and Best Practices  Always explicitly state your supported runtime version in the application configuration file <? xml version="1. For more information please see any automatically created Assemblyinfo.0" ?> <configuration> <startup> <supportedRuntime version="1.0" /> </startup> </configuration>  Populate all fields in AssemblyInfo.0. Inc.5000.")] [assembly: AssemblyTrademark("Company")] [assembly: AssemblyCulture("")] [assembly:CLSCompliant(true)] Pradeep Kumar Mishra Page 47 .0" /> <supportedRuntime version="2.")] [assembly: AssemblyCopyright("Copyright (c) "+ Year + " Company .1.cs file. description and copyright notice.5500.cs such as company name.

com/Articles/getArticle.VS. Following copyright information should be used.cs  All assembly references in the same solution should use relative path.C# Coding Guidelines and Best Practices  Put copyright notice also on the top of every cs file. #region Copyright (c) 2005-2006 Company .80).com/en-us/library/ms229042(en-US.gotdotnet. (This is by default in Visual Studio)  Always sign your assemblies. E. Inc. including client applications. 6 References:  http://msdn2.aspx  http://www. To add copyright notice when a new class is created change the following template(For VS . 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.NET 2003\VC#\VC#Wizards\CSharpAddClassWiz\Templates\1033\ NewCSharpFile. // //The copyright to the computer software herein is proprietary //and remains the property of Company.g.aspx?articleID=336  http://www.aspx  http://www.tech. All rights reserved // ************************************************************** // Copyright (c) 2005 Company.cs file.net/TechNotes/SharpDevelopCodingStyle03.icsharpcode.NET 2003) <VS Installation Directory>\Microsoft Visual Studio . // ************************************************************** #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.edu/Cpt/Courses/cpt355/C_Sharp_Coding_Standards _and_Guidelines.pdf Pradeep Kumar Mishra Page 48 .purdue. For more information regarding signing assemblies please see any automatically created Assemblyinfo.htm  http://www.  Make sure there are no cyclic references among assemblies.csharpfriends.com/Team/FxCop/docs/rules/NamingRules.microsoft.

Notice that both variables have integer data types. Contrary to popular belief. Hungarian notation.  You can often tell an identifier‟s type by the usage. and both are intended to hold a count of something. o Type information is provided in the debugger. Hungarian notation is not recommended in c# by Microsoft. such as GetXmlReader() or LoadControl(). but it is very clear that rowCount is a count of a rows. it is rarely necessary as code is modularized enough so that the declaration is often visible or easily found if there is a question as to an identifier‟s type. Anyone reviewing the following code: rowCount = userData. Prefixing a variable with a tag indicating its data type is better known as System notation.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. colCount = userData. Pradeep Kumar Mishra Page 49 . but. seen by “mousing over” the identifier. and maintain because it helps correct code look correct. 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. and colCount is a count of columns.NET IDE offers several ways to quickly identify an object‟s type: o Tooltip. it should give someone reviewing the code a clue as to what the variable contains and what it is intended to be used for. Example of Hungarian notation for variables: int rowCount = 0. and should not be used. debug.Count.Columns.Count. and makes code easier to write. … would be able to spot an error in the usage of the variables. rather. Some of the reasons why not to use Hungarian notations are as follows…  In object-oriented programming.Rows.  The VS. o Intellisense tells you the type. gives a readable quality to the code. int colCount = 0. when used properly. this does not mean that the prefix should indicate the data type of the variable. and incorrect code look incorrect.