AvSol CSharp 3.0 Coding Guidelines

32
C# 3.0 Coding Guidelines Guidelines for .NET development www.avivasolutions.nl blog.avivasolutions.nl March 2009 Dennis Doomen

Transcript of AvSol CSharp 3.0 Coding Guidelines

Page 1: AvSol CSharp 3.0 Coding Guidelines

C# 3.0 Coding Guidelines Guidelines for .NET development

www.avivasolutions.nl blog.avivasolutions.nl

March 2009 Dennis Doomen

Page 2: AvSol CSharp 3.0 Coding Guidelines

C# 3.0 Coding Guidelines Guidelines for .NET Development

[ II ]

March 2009 Dennis Doomen

www.avivasolutions.nl blog.avivasolutions.nl

Contents

1 General ........................................................................................................................................... 1

1.1 Introduction ............................................................................................................................................. 1

1.2 Goals ...................................................................................................................................................... 1

1.3 Visual Studio Code Analysis and Source Analysis ................................................................................. 1

1.4 Guidelines, not a standard ...................................................................................................................... 1

1.5 What about design patterns? .................................................................................................................. 2

1.6 Feedback and disclaimer ........................................................................................................................ 2

1.7 Contributions .......................................................................................................................................... 2

1.8 History .................................................................................................................................................... 2

2 Design Guidelines ......................................................................................................................... 3

3 Maintainability Guidelines ........................................................................................................... 8

4 Naming Guidelines ..................................................................................................................... 15

5 Performance Guidelines ............................................................................................................ 19

6 Usage Guidelines ........................................................................................................................ 20

7 Documentation Guidelines ........................................................................................................ 22

8 Layout Guidelines ....................................................................................................................... 24

9 Resources .................................................................................................................................... 26

10 List of Code Analysis Rules ...................................................................................................... 27

Page 3: AvSol CSharp 3.0 Coding Guidelines

C# 3.0 Coding Guidelines Guidelines for .NET Development

[ 1 ]

March 2009 Dennis Doomen

www.avivasolutions.nl blog.avivasolutions.nl

1 General

1.1 Introduction

This document attempts to provide useful and pragmatic guidelines for programming in C# 3.0 which we at Aviva

Solutions already use in our day-to-day work. This idea started in 2002 when Vic Hartog (Philips Medical Systems) and

I were assigned the task of writing up a coding standard for C# 1.0. Since then, I've tried to publish a similar document

for C# 2.0, but because of a change of employer, I never officially published it other than through blog posts. In the last

couple of months I’ve received several requests from the community for an updated version of this document,

preferably covering C# 3.0 as well. Moreover, I have become particularly fond of the power that Visual Studio's Code

Analysis (FxCop) provides.

1.2 Goals

The coding guidelines have been written up for several reasons that should help writing high quality code that is easy

to understand code and easy to maintain by (future) team members. Aviva Solutions applies code reviews to validate

code quality, so it is important that all members of a project use the same style of coding. Style in this sense means

using common constructs, writing proper documentation and code comments, and organizing code using a common

layout.

Although complying with coding guidelines may seem to appear as undesired overhead or may limit creativity, this

approach has already proven its value for many years. Moreover, not all coding guidelines have a clear rationale. Many

of them are simply choices we made at Aviva Solutions. Additional goals include:

Preventing common mistakes and pitfalls.

Preventing language constructs that are less comprehensive.

Promoting object-oriented development.

1.3 Visual Studio Code Analysis and Source Analysis

Since the introduction of the first version of this document, Microsoft has spent a considerable amount of effort in

helping us automating the review process. Static Code Analysis (FxCop) supports a wide range of rules covering both

aspects such as this document covers and design guidelines on the usage of the .NET Framework. In this edition of the

coding guidelines, we've removed all overlap with Code Analysis and added a list of recommended rules.

Another more recent effort is Source Analysis, a.k.a. StyleCop. But even though we really like it, its current ruleset does

not allow sufficient flexibility to be pragmatic. For instance, we do want all public members to have proper

documentation, but for many private members we don't need one. The current version of StyleCop does not allow you

to choose this as an option yet.

1.4 Guidelines, not a standard

The document does not state that projects must comply with these guidelines, neither does it say which guidelines are

more important than others. However, we encourage projects to decide themselves what guidelines are important,

what deviations a project will use, who is the consultant in case doubts arise, and what kind of layout must be used for

source code. Obvious, you should make these decisions before starting the real coding work.

In general, generated code should not need to comply with coding guidelines. However, if it is possible to modify the

templates used for generation, try to make them generate code that complies as much as possible.

Page 4: AvSol CSharp 3.0 Coding Guidelines

C# 3.0 Coding Guidelines Guidelines for .NET Development

[ 2 ]

March 2009 Dennis Doomen

www.avivasolutions.nl blog.avivasolutions.nl

1.5 What about design patterns?

We've received a few suggestions that were great on itself, but unfortunately where too much related to design

principles and patterns. Even though I would love to to add these as well, it would have increased the size of the

document significantly. Instead, I'd like to refer you to notable people like Martin Fowler, Jimmy Nilsson and Jeremy D.

Miller.

1.6 Feedback and disclaimer

This document has been compiled using many contributions from both (ex) colleagues, sources from the Internet, and

many years of developing in C#. If you have questions, comments or suggestions, please let us know by sending me

an email at [email protected]. We will try to revise and republish this document with new insights,

experiences and remarks on a regular basis. Notice though that it merely reflects our view on proper C# code so Aviva

Solutions will not be liable for any direct or indirect damages caused by applying the guidelines of this document.

It is allowed to copy, adapt, and redistribute this document and its companion quick reference guide for non-

commercial purposes or internal usage. However, you may not republish this document, or publish or distribute any

adaptation of this document for commercial use without first obtaining express written approval from Aviva Solutions.

1.7 Contributions

The following (prior) colleagues and members from the .NET community have contributed to this document both

directly and indirectly (through web sites, articles and on-line discussions):

Erwin Derksen (Ordina), Leendert Versluijs (Ordina), Matthijs den Haan (Ordina), John Dekkers (Ordina), Juwal Lovy

(IDesign), Peter Ritchie (Independent MVP), Vic Hartog (Philips Medical Systems), William van Strien (Ordina), Martin

Opdam (Aviva Solutions), Stephan Bookholt (Aviva Solutions), Jo-Wen Mei (Oosterkamp Training)

1.8 History

Jan 2006 Initial version based on the Philips C# 1.0 Standard Dennis Doomen

Jan 2009 Major overhaul. Introduced recommended use of Code Analysis /

FxCop and removed overlapping guidelines. Added C# 3.0 / LINQ

coding guidelines.

Dennis Doomen

Mar 2009 First publication on the internet Dennis Doomen

Page 5: AvSol CSharp 3.0 Coding Guidelines

C# 3.0 Coding Guidelines Guidelines for .NET Development

[ 3 ]

March 2009 Dennis Doomen

www.avivasolutions.nl blog.avivasolutions.nl

2 Design Guidelines

AV1001 Do use a public static readonly field to define predefined object instances

For example, consider a Color struct that stores a color internally as red, green, and blue components and this class

has a constructor taking a numeric representation, then this class may expose several predefined colors like this.

public struct Color

{

public static readonly Color Red = new Color(0xFF0000);

public static readonly Color Black = new Color(0x000000);

public static readonly Color White = new Color(0xFFFFFF);

public Color(int redGreenBlue)

{

// implementation

}

}

AV1002 Do mark classes that only contain static members as static

The advantage of using a static class is that the compiler can make sure that no instance members are accidentally

defined. The compiler will guarantee that instances of this class cannot be created and hence, relieves you of creating

a private constructor such as was required in C# 1.0. Use a static class to contain methods that are not associated with

a particular instance. For example:

public static class EuroConversion

{

public static Decimal FromUSD(Decimal inUsd) { ... }

public static Decimal ToUSD(Decimal inEuro) { ... }

}

AV1003 Do seal a class unless it has been designed for inheritance

Defining a class sealed ensures that other classes cannot derive from it. Unless you have thought through the

consequences of deriving from your class and have provided appropriate measurements (e.g. defined protected default

constructors, defined virtual methods and properties, etc), define the class sealed. For example:

public sealed class Book

{

public Book() { … }

}

AV1010 Don’t hide inherited members with the new keyword

Not only does the new keyword break Polymorphism, one of the most essential object-orientation principles, it also

makes subclasses more difficult to understand. Consider the following two classes:

public class Book

{

public virtual void Print()

{

Console.WriteLine("Printing Book");

}

}

public class PocketBook : Book

{

Page 6: AvSol CSharp 3.0 Coding Guidelines

C# 3.0 Coding Guidelines Guidelines for .NET Development

[ 4 ]

March 2009 Dennis Doomen

www.avivasolutions.nl blog.avivasolutions.nl

public new void Print()

{

Console.WriteLine("Printing PocketBook");

}

}

This will cause the following behavior which is not something you normally expect from class hierarchies.

Book pocketBook = new PocketBook();

pocketBook.Print(); // Will output "Printing PocketBook "

((Book)pocketBook).Print(); // Will output "Printing Book"

It should not make a difference whether you call Print through the base class or the derived class.

AV1011 It should be possible to treat a derived object as if it were a base class object

In other words, it shall be possible to use a reference to an object of a derived class wherever a reference to its base

class object is used without knowing the specific derived class. This rule is also known as the Liskov Substitution

Principle (LSP). Please note that an interface is also regarded as a base class in this context.

AV1015 Do allow properties to be set in any order

Properties should be stateless with respect to other properties, i.e. there should not be a difference between first

setting property DataSource and then DataMember, and vice versa.

AV1016 Do use a method, rather than a property, in the following situations

The operation is orders of magnitude slower than a field set would be. If you are even considering providing an

asynchronous version of an operation to avoid blocking the thread, it is very likely that the operation is too

expensive to be a property. In particular, operations that access the network or the file system (other than once for

initialization) should most likely be methods, not properties.

The operation is a conversion, such as the Object.ToString method.

The operation returns a different result each time it is called, even if the parameters didn’t change. For example,

the NewGuid method returns a different value each time it is called.

The operation has a significant and observable side effect. Note that populating an internal cache is not generally

considered an observable side effect.

The operation returns a copy of an internal state (this does not include copies of value type objects returned on the

stack).

AV1020 Don’t create a constructor that does not yield a fully initialized object

Only create constructors that construct objects that are fully initialized. There shall be no need to set additional

properties. A private constructor is exempt from this rule.

AV1025 Don’t return an array

This allows calling code to change the items in the array. Even though callers cannot replace the array itself with

another array, they can still replace an item within the array with another item. This may cause unexpected effects

within the class that owns the array. Instead, return an IEnumerable<T>, or, if the number of items is important for

the caller, an ICollection<T>.

Page 7: AvSol CSharp 3.0 Coding Guidelines

C# 3.0 Coding Guidelines Guidelines for .NET Development

[ 5 ]

March 2009 Dennis Doomen

www.avivasolutions.nl blog.avivasolutions.nl

AV1026 Don’t use readonly fields of arrays

If you do, the array is read-only and cannot be changed, but the elements in the array can be changed. The following

code example demonstrates how the elements of the read-only array countries can be changed.

private readonly string[] countries = { “Netherlands”, “Germany” };

// Causes a compile error due to the readonly definition

countries = new[] { “Austria” };

// Will compile and run happily, but was it intended??

countries[0] = “France”;

AV1027 String and array properties should never return a null reference

Returning null can be unexpected by the caller. The general rule is that null, an empty string (""), and an empty

array (0 items) should be treated the same way. Always return an empty array and an empty string instead of a null

reference.

AV1030 Avoid using friend assemblies

Using the [InternalsVisibleTo] attribute can lead to dirty hacks and bypassing basic OO principles. Do only use

friend assemblies in well-known solution like the Memento design pattern or to grant unit test code access to certain

internal members.

AV1040 Provide a rich and meaningful exception message text

The message should explain the cause of the exception and clearly describe what needs to be done to avoid the

exception.

AV1041 Do throw the most specific exception that is appropriate

For example, if a method receives a null argument, it should throw ArgumentNullException instead of its base

type ArgumentException.

AV1042 Don’t swallow errors by catching non-specific exceptions

Avoid swallowing errors by catching non-specific exceptions, such as Exception, SystemException, and so on, in

application code. There are cases when swallowing errors in applications is acceptable, but such cases are rare.

An application should not swallow exceptions that can result in an unexpected or exploitable state. If you cannot predict

all possible causes of an exception and ensure that malicious code cannot exploit the resulting application state, you

should allow the application to terminate instead of swallowing the exception.

AV1043 Prefer throwing existing exceptions

Use existing exceptions residing in the System namespaces instead of creating custom exception types.

AV1044 Avoid side-effects when throwing recoverable exceptions

When you throw a recoverable exception, make sure that the object involved stays in a usable and predictable state.

With usable it is meant that the caller can catch the exception, take any necessary actions, and continue to use the

object again. With predictable is meant that the caller can make logical assumptions on the state of the object.

Page 8: AvSol CSharp 3.0 Coding Guidelines

C# 3.0 Coding Guidelines Guidelines for .NET Development

[ 6 ]

March 2009 Dennis Doomen

www.avivasolutions.nl blog.avivasolutions.nl

For instance, if during the process of adding a new item to a list, an exception is raised, then the caller may safely

assume that the item has not been added, and another attempt to re-add it is possible.

AV1050 Don’t make assumptions on the object’s state after raising an event

Prepare for any changes to the current object’s state while executing an event handler. The event handler may have

called other methods or properties on you class that changed the object’s state.

AV1051 Do always check an event handler delegate for null

An event that has no subscribers is null, so always make sure that the delegate is not null before invoking it.

AV1052 Do use a protected virtual method to raise each event

This is applicable only to non-static events on unsealed classes, not to structures, sealed classes, or static events.

Complying with this guideline allows derived classes to handle a base class event by overriding the protected method.

The name of the protected virtual method should be the same as the event name prefixed with On. For example, the

protected virtual method for an event named TimeChanged is named OnTimeChanged.

Important Derived classes that override the protected virtual method are not required to call the base class

implementation. The base class must continue to work correctly even if its implementation is not called.

AV1053 Consider providing property-changed events

Consider providing events that are raised when certain properties are changed. Such an event should be named

PropertyChanged, where Property should be replaced with the name of the property with which this event is

associated.

Note If your class has many properties that require corresponding events, consider implementing the

INotifyPropertyChanged interface instead.

AV1054 Don’t pass null as the sender parameter when raising an event

Often, an event handler is used to handle similar events from multiple senders. The sender argument is then used to

get to the source of the event. Always pass a reference to the source (typically this) when raising the event.

Furthermore don’t pass null as the event data parameter when raising an event. If there is no event data, pass

EventArgs.Empty instead of null.

Exception On static events, the sender parameter should be null.

AV1060 Do only implement casts that operate on the complete object

In other words, don’t cast one type to another using a member of the source type. For example, a Button class has a

string property Name. It is valid to cast the Button to the Control (since Button is a Control), but it is not valid to

cast the Button to a string by returning the value of the Name property.

AV1061 Don’t generate a semantically different value with a cast

For example, it is appropriate to convert a Time or TimeSpan into an Int32. The Int32 still represents the time or

duration. It does not, however, make sense to convert a file name string such as c:\mybitmap.gif into a Bitmap

object using a cast operation.

Page 9: AvSol CSharp 3.0 Coding Guidelines

C# 3.0 Coding Guidelines Guidelines for .NET Development

[ 7 ]

March 2009 Dennis Doomen

www.avivasolutions.nl blog.avivasolutions.nl

AV1062 Avoid casting to and from System.Object in code that uses generics

Use where contraints or the as operator instead. For example:

class SomeClass

{}

// Don't

class MyClass<T>

{

void SomeMethod(T t)

{

object temp = t;

SomeClass obj = (SomeClass) temp;

}

}

// Do

class MyClass<T> where T : SomeClass

{

void SomeMethod(T t)

{

SomeClass obj = t;

}

}

AV1070 Don’t add extension methods to the same namespace as the extended class

Even though it may seem convenient to add extension methods related to the String class in the System

namespace, this may cause conflicts with future versions of the .NET Framework.

AV1075 Adhere to the LINQ Design Guidelines for custom IQueryable implementations

Developing a custom implementation of the IQueryable interface requires a great deal of background information on

the .NET Framework and the Expression class hierarchy. Make sure you read the guidelines written down by

Microsoft on this. See http://blogs.msdn.com/mirceat/archive/2008/03/13/linq-framework-design-guidelines.aspx

AV1076 Do evaluate the result of a LINQ expression before returning it

Consider the following code snippet

public IEnumerable<GoldMember> GetGoldMemberCustomers()

{

const decimal GoldMemberThresholdInEuro = 1000000;

var q = from customer in db.Customers

where customer.Balance > GoldMemberThresholdInEuro

select new GoldMember(customer.Name, customer.Balance);

return q;

}

Since LINQ queries use deferred execution, returning q will actually return the expression tree representing the above

query. Each time the caller evaluates this result using a foreach or something similar, the entire query is re-executed

resulting in new instances of GoldMember every time. Consequently, you cannot use the == operator to compare

multiple GoldMember instances. Instead, always explicitly evaluate the result of a LINQ query using ToList(),

ToArray() or similar methods.

Page 10: AvSol CSharp 3.0 Coding Guidelines

C# 3.0 Coding Guidelines Guidelines for .NET Development

[ 8 ]

March 2009 Dennis Doomen

www.avivasolutions.nl blog.avivasolutions.nl

3 Maintainability Guidelines

AV1501 Avoid using names that can be mistaken with other names.

Although technically allowed, the following statement is quite confusing.

bool b001 = (lo == l0) ? (I1 == 11) : (lOl != 101);

AV1505 Do name assemblies after their contained namespace

To allow storing assemblies in the Global Assembly Cache (GAC) the filename of an assembly must be unique.

Therefore, use the namespace name as a prefix of the name of the assembly. As an example, consider a group of

classes organized under the namespace AvivaSolutions.Web.Binding exposed by a certain assembly.

According to this guideline, that assembly should be called AvivaSolutions.Web.Binding.dll.

All DLLs should be named according to the pattern <Company>.<Component>.dll where <Company> refers to

your company’s name and <Component> contains one or more dot-separated clauses. For example

AvivaSolutions.Web.Controls.dll.

Exception If you decide to combine classes from multiple unrelated namespaces into one assembly, consider post

fixing the assembly with Core, but do not use that suffix in the namespaces. For instance,

AvivaSolutions.Consulting.Core.dll.

AV1506 Do name a source file to the class it contains

Also, use Pascal casing for naming the file and don’t use underscores.

AV1507 Do limit the contents of a source code file to one class

Exception It is allowed to place small helper classes such as the ones that provide event data (subclasses of

EventArgs) in the same file as the corresponding main class. However, place them after the main class.

AV1508 Do name a source file to the logical function of the partial type

When using partial types and allocating a part per file, name each file after the logical part that part plays. For example:

// In MyClass.cs

public partial class MyClass

{...}

// In MyClass.Designer.cs

public partial class MyClass

{...}

AV1510 Do use using instead of fully qualified type names

Limit usage of fully qualified type names to prevent name clashing. For example:

Don’t:

var list = new System.Collections.Generic.List<string>();

Do:

using System.Collections.Generic;

var list = new List<string>();

Page 11: AvSol CSharp 3.0 Coding Guidelines

C# 3.0 Coding Guidelines Guidelines for .NET Development

[ 9 ]

March 2009 Dennis Doomen

www.avivasolutions.nl blog.avivasolutions.nl

If you do need to prevent name clashing, use a using directive to assign an alias:

using Label = System.Web.UI.WebControls.Label;

AV1515 Don’t use "magic numbers"

Don’t use literal values, either numeric or strings, in your code other than to define symbolic constants. For example:

public class Whatever

{

public static readonly Color PapayaWhip = new Color(0xFFEFD5);

public const int MaxNumberOfWheels = 18;

}

Strings intended for logging or tracing are exempt from this rule. Literals are allowed when their meaning is

clear from the context, and not subject to future changes, For example:

mean = (a + b) / 2; // okay

WaitMilliseconds(waitTimeInSeconds * 1000); // clear enough

If the value of one constant depends on the value of another, do attempt to make this explicit in the code. For example,

don’t

public class SomeSpecialContainer

{

public const int MaxItems = 32;

public const int HighWaterMark = 24; // at 75%

}

but do

public class SomeSpecialContainer

{

public const int MaxItems = 32;

public const int HighWaterMark = 3 * MaxItems / 4; // at 75%

}

Note An enumeration can often be used for certain types of symbolic constants.

AV1520 Do use var only when the type is very obvious

Only use var as the result of a LINQ query, or if the type is very obvious from the same statement and using it would

improve readability.

Don't

var i = 3; // what type? int? uint? float?

var imyfoo = MyFactoryMethod.Create("arg"); // Not obvious what base-class or

// interface to expect. Also difficult

// to refactor if you can't search for

// the class

Do:

Page 12: AvSol CSharp 3.0 Coding Guidelines

C# 3.0 Coding Guidelines Guidelines for .NET Development

[ 10 ]

March 2009 Dennis Doomen

www.avivasolutions.nl blog.avivasolutions.nl

var q = from order in orders where order.Items > 10 and order.TotalValue > 1000;

var repository = new RepositoryFactory.Get<IOrderRepository>();

var list = new ReadOnlyCollection<string>();

In all of three above examples it is clear what type to expect.

AV1521 Do initialize variables at the point of declaration, if possible

Avoid the C and Visual Basic styles where all variables have to be defined at the beginning of a block, but rather define

and initialize each variable at the point where it is needed.

AV1522 Do use constant fields for variables that will never change

Making it const ensures that the same value is used consistently throughout your code, and it clarifies the exact

meaning of the constant to other co-developers. The compiler inserts the values of const fields directly into the calling

code, which means that const values can never be changed without the risk of introducing a compatibility issue. For

example:

private const int MaximumUsers = 100;

Exception If the value of a constant field must be calculated at run-time (in the static constructor), use a static read-

only field instead.

AV1523 Favor Object and Collection Initializers over separate statements

Instead of

var startInfo = new ProcessStartInfo(“myapp.exe”);

process.StandardOutput = Console.Output;

process.UseShellExecute = true;

Use Object Initializers

var startInfo = new ProcessStartInfo(“myapp.exe”)

{

StandardOutput = Console.Output,

UseShellExecute = true

};

Similarly, instead of

var countries = new List<string>();

countries.Add(“Netherlands”);

countries.Add(“United States”);

Use Collection Initializers

var countries = new List<string> { “Netherlands”, “United States” };

Note Do not violate guideline AV1020 by not providing a proper parameterized constructor.

AV1525 Don’t make explicit comparisons to true or false

It is usually bad style to compare a bool-type expression to true or false. For example:

while (condition == false) // wrong; bad style

while (condition != true) // also wrong

while (((condition == true) == true) == true) // where do you stop?

while (condition) // OK

Page 13: AvSol CSharp 3.0 Coding Guidelines

C# 3.0 Coding Guidelines Guidelines for .NET Development

[ 11 ]

March 2009 Dennis Doomen

www.avivasolutions.nl blog.avivasolutions.nl

AV1526 Do use an enumeration instead of a list of strings if the list of values is finite

If a variable can have a limited set of constant string values, use an enumeration for defining the valid values. Using the

enumeration instead of a constant string allows compile-time checking and prevents typos.

AV1530 Don’t change a loop variable inside a for loop block

Updating the loop variable within the loop body is generally considered confusing, even more so if the loop variable is

modified in more than one place. Although this rule also applies to foreach loops, an enumerator will typically detect

changes to the collection the foreach loop is iteration over.

for (int index = 0; index < 10; ++index)

{

if (some condition)

{

index = 11; // Wrong! Use „break‟ or „continue‟ instead.

}

}

AV1531 Do update loop variables close to where the loop condition is checked

This makes understanding the loop much easier.

int index = 100;

bool continueLoop = false;

do

{

// Put your loop logic here

// Keep these two lines close to the „while‟ statement.

continueLoop = check if some condition is still met.

--index;

}

while ((index > 0) && (continueLoop))

AV1535 Do use a block with all flow control keywords, even if it is empty

Please note that this also avoids possible confusion in statements of the form:

if (b1) if (b2) Foo(); else Bar(); // which „if‟ goes with the „else‟?

// The right way:

if (b1)

{

if (b2)

{

Foo();

}

else

{

Bar();

}

}

Always surround the statements if, else, do, while, for and foreach, with a { and a }, even though the

language does not require it.

Page 14: AvSol CSharp 3.0 Coding Guidelines

C# 3.0 Coding Guidelines Guidelines for .NET Development

[ 12 ]

March 2009 Dennis Doomen

www.avivasolutions.nl blog.avivasolutions.nl

AV1536 Do add a default block after the last case in a switch statement

Add a descriptive comment if the default block is supposed to be empty. Moreover, if that block is not supposed to be

reached throw an InvalidOperationException to detect future changes that may fall through the existing cases.

This ensures better code, because all paths the code can travel has been thought about.

void Foo(string answer)

{

switch (answer)

{

case "no":

Console.WriteLine("You answered with No");

break;

case "yes":

Console.WriteLine("You answered with Yes");

break;

default:

// Not supposed to end up here.

throw new InvalidOperationException("Unexpected answer: " + answer);

}

}

AV1537 Do code every if-else if statement with an else-part

The intention of this rule, which applies to else-if constructs, is the same as the previous rule. For example.

void Foo(string answer)

{

if (answer == "no")

{

Console.WriteLine("You answered with No");

}

else if (answer == "yes")

{

Console.WriteLine("You answered with Yes");

}

else

{

// What should happen when this point is reached? Ignored? If not,

// throw an InvalidOperationException.

}

}

AV1540 Avoid multiple return statements

One entry, one exit is a sound principle and keeps control flow readable.

Exception In some cases, such as when preconditions are checked and that condition is not met, it may be good

practice to exit a method immediately.

AV1545 Don’t use selection statements instead of a simple assignment or initialization

Express your intentions directly. For example, rather than

bool pos;

if (val > 0)

{

pos = true;

}

else

Page 15: AvSol CSharp 3.0 Coding Guidelines

C# 3.0 Coding Guidelines Guidelines for .NET Development

[ 13 ]

March 2009 Dennis Doomen

www.avivasolutions.nl blog.avivasolutions.nl

{

pos = false;

}

write

bool pos = (val > 0); // initialization

AV1546 Prefer conditional statements instead of simple if-else constructs

For example, instead of

string result;

if (someString != null)

{

result = someString;

}

else

{

result = “Unavailable”;

}

return result;

write

return someString ?? “Unavailable”;

AV1550 Do explicitly define the scope of a type or member

Even though types and members have a default scope, always explicitly define whether the scope is public,

private or internal. For example:

class Cat {}

// Better: same visibility as Cat but more explicit

internal class Dog

{

int length;

// Better: same scope as length, but more explicit

private int height;

}

AV1551 Do implement the most complete overload of a method or constructor and call it from the other overloaded

methods or constructors

This guideline only applies to overloads that are intended for providing optional arguments. Consider for example the

following code snippet:

public class MyString

{

private string someText;

public MyString(string s)

{

this.someText = s;

}

public int IndexOf(string s)

{

Page 16: AvSol CSharp 3.0 Coding Guidelines

C# 3.0 Coding Guidelines Guidelines for .NET Development

[ 14 ]

March 2009 Dennis Doomen

www.avivasolutions.nl blog.avivasolutions.nl

return IndexOf(s, 0, someText.Length);

}

public int IndexOf(string s, int startIndex)

{

return IndexOf(s, startIndex, someText.Length - startIndex );

}

public int IndexOf(string s, int startIndex, int count)

{

return someText.IndexOf(s, startIndex, count);

}

}

The class MyString provides three overloads for the IndexOf method, but two of them simply call the one with the

most arguments. Notice that the same rule applies to class constructors; implement the most complete overload and

call that one from the other overloads using the this() operator.

Important If you also want to allow derived classes to override these methods, define the most complete overload as a

protected virtual method that is called by all overloads.

public class MyString

{

// same as above …

public int IndexOf(string s, int startIndex, int count)

{

return InternalIndexOf(s, startIndex, count);

}

protected virtual int InternalIndexOf(string s, int startIndex, int count)

{

return someText.IndexOf(s, startIndex, count);

}

}

AV1560 Do be consistent in the ordering of parameters in overloaded members

Parameters with the same name should appear in the same position in all overloads.

AV1561 Avoid methods with more than 5 arguments

If you end up with a method with more than five arguments, use a structure or class for passing multiple arguments.

Moreover, a method with that many arguments may imply that the responsibilities have not been evenly distributed

over the classes in a component.

AV1562 Don’t use ref or out parameters

Ref and out parameters make code less understandable and therefore may introduce bugs. Prefer returning

compound objects instead.

AV1570 Do always check the result of an as operation

If you use as to obtain a certain interface reference from an object, always ensure that this operation does not return

null. Failure to do so may cause a NullReferenceException at a much later stage if the object did not implement

that interface.

Page 17: AvSol CSharp 3.0 Coding Guidelines

C# 3.0 Coding Guidelines Guidelines for .NET Development

[ 15 ]

March 2009 Dennis Doomen

www.avivasolutions.nl blog.avivasolutions.nl

4 Naming Guidelines

AV1701 Do use proper US-English

All identifiers should be named using words from the English language.

Choose easily readable identifier names. For example, HorizontalAlignment is more readable than

AlignmentHorizontal.

Favor readability over brevity. The property name CanScrollHorizontally is better than ScrollableX (an

obscure reference to the X-axis).

Avoid using identifiers that conflict with keywords of widely used programming languages.

Exception In some languages it may appear counterintuitive to translate domain-specific non-English terms into its

English counterparts. In those cases, it may be wise to keep the original term from the native language. For instance,

GetZaak for getting a legal case. However, Code Analysis also performs a spelling check, so you may need to add

those terms to a Custom Code Analysis Dictionary.

AV1705 Don’t prefix member fields

Don’t use a prefix for field names. For example, Don’t use g_ or s_ to distinguish static versus non-static fields. In

general, a method in which it is difficult to distinguish local variables from member fields, is too big. Examples of

incorrect identifier names are: _currentUser, mUserName, m_loginTime.

AV1706 Do use abbreviations with care

Don’t use abbreviations or acronyms as parts of identifier names. For example, use OnButtonClick rather than

OnBtnClick. Avoid single character variable names, such as i or t. Use index or temp instead.

Exceptions Use well-known abbreviations that are widely accepted such as UI instead of UserInterface.

AV1707 Do name an identifier according its meaning and not its type

Do use semantically interesting names rather than language-specific keywords for type names. For example,

GetLength is a better name than GetInt.

Don’t use terms like Enum, Class or Struct in a name.

Do use a generic Common Type System (CTS) type name, rather than a language-specific name in the rare cases

when an identifier has no semantic meaning beyond its type. For example, a method that converts data to Int16

should be named ToInt16, not ToShort because Short is the language-specific type name for Int16.

Identifiers that refer to an array or collection should have a plural name.

AV1708 Do name classes, interfaces and value types with nouns, noun phrases or adjective phrases

Do name classes, interfaces, and value types with nouns, noun phrases, or occasional adjective phrases, and don’t

give class names a prefix (such as the letter C).

Bad examples:

SearchExamination: in this case it was a page for searching for examinations

Common: does not end with a noun,and does not explain what its purpose is

Page 18: AvSol CSharp 3.0 Coding Guidelines

C# 3.0 Coding Guidelines Guidelines for .NET Development

[ 16 ]

March 2009 Dennis Doomen

www.avivasolutions.nl blog.avivasolutions.nl

SiteSecurity: although the name is technically okay, it does not say anything about its purpose

Good examples:

BusinessBinder, SmartTextBox, or EditableSingleCustomer.

AV1709 Do name generic type parameters with descriptive names

The following guidelines cover selecting the correct names for generic type parameters.

Do name generic type parameters with descriptive names, unless a single-letter name is completely self

explanatory and a descriptive name would not add value. For example: IDictionary is an example of an

interface that follows this guideline.

Use the letter T as the type parameter name for types with one single-letter type parameter.

Do prefix descriptive type parameter names with the letter T.

Consider indicating constraints placed on a type parameter in the name of parameter. For example, a parameter

constrained to ISession may be called TSession.

AV1710 Don’t repeat the name of a class or enumeration in its members

class Employee

{

// Wrong!

static GetEmployee() {}

DeleteEmployee() {}

// Right

static Get() {...}

Delete() {...}

// Also correct.

AddNewJob() {...}

RegisterForMeeting() {...}

}

AV1711 Do name members similarly to members of .NET Framework classes

Stay close to the naming philosophy of the .NET Framework. Developers are already accustomed to the naming

patterns .NET Framework classes use, so following this same pattern helps them find their way in your classes as well.

For instance, if you define a class that behaves like a collection, provide members like Add, Remove and Count

instead of AddItem, Delete or NumberOfItems.

AV1715 Do properly name properties

Do name properties with nouns, noun phrases, or occasionally adjective phrases.

Do name boolean properties with an affirmative phrase. E.g. CanSeek instead of CantSeek.

Consider prefixing Boolean properties with Is, Has, Can, Allows, or Supports.

Consider giving a property the same name as its type. When you have a property that is strongly typed to an

enumeration, the name of the property can be the same as the name of the enumeration. For example, if you have

an enumeration named CacheLevel, a property that returns one of its values can also be named CacheLevel.

Page 19: AvSol CSharp 3.0 Coding Guidelines

C# 3.0 Coding Guidelines Guidelines for .NET Development

[ 17 ]

March 2009 Dennis Doomen

www.avivasolutions.nl blog.avivasolutions.nl

AV1720 Do name methods using verb-object pair

Name methods using a verb-object pair, such as ShowDialog. A good name should give a hint on the what of a

member, and if possible, the why.

interface IEmployeeRepository

{

Employee[] First() { } // Wrong: What does first mean? How many?

Employee[] GetFirstFive() {} // Better

Employee[] GetFiveMostRecent(){} // Best: self-describing

void Add(Employee employee) {} // Although not using verb-object pair;

// the type name is clear enough

}

AV1725 Do name namespaces according a well-defined pattern

All namespaces should be named according to the pattern

<Company>.(<Product>|<Technology>)[.<Feature>][.<Subnamespace>]

For instance: Microsoft.WindowsMobile.DirectX.

Note Don’t use the same name for a namespace and a type in that namespace. For example, don’t use Debug for a

namespace name and also provide a class named Debug in the same namespace.

AV1730 Do add the suffix Callback to delegates related to callback methods

Delegates that are used to refer to a callback method (so not an event) must be suffixed with Callback. For example:

public delegate void AsyncIOFinishedCallback(IpcClient client, string message);

AV1735 Do use a verb or verb phrase to name an event

Do name events with a verb or a verb phrase. For example: Click, Deleted, Closing, Minimizing, and

Arriving. For example, the declaration of the Search event may look like this:

public event SearchEventHandler Search;

AV1736 Don’t add an Event suffix to the name of an event

AV1737 Do use -ing and -ed to express pre-events and post-events

Do give event names a concept of before and after, using the present and past tense. For example, a close event that

is raised before a window is closed would be called Closing and one that is raised after the window is closed would

be called Closed. Don’t use Before or After prefixes or suffixes to indicate pre and post events. Suppose you want

to define events related to the deletion process of an object. Avoid defining the Deleting and Deleted events as

BeginDelete and EndDelete.

Do define those events as follows:

Deleting: Occurs just before the object is getting deleted

Delete: Occurs when the object needs to be deleted by the event handler.

Deleted: Occurs when the object is already deleted.

Page 20: AvSol CSharp 3.0 Coding Guidelines

C# 3.0 Coding Guidelines Guidelines for .NET Development

[ 18 ]

March 2009 Dennis Doomen

www.avivasolutions.nl blog.avivasolutions.nl

AV1738 Do prefix an event handler with On

It is good practice to prefix the method that handles an event with On. For example, a method that handles the

Closing event could be named OnClosing.

Exception In some situations you might be faced with multiple classes exposing the same event name. To allow

separate event handlers use a more intuitive name for the event handler, as long as it is prefixed with On.

AV1745 Group extension methods in a class suffixed with Extensions

If the name of an extension method conflicts with another member or extension method, you must prefix the call with

the class name. Having them in a dedicated class with the Extensions suffix improves readability.

Page 21: AvSol CSharp 3.0 Coding Guidelines

C# 3.0 Coding Guidelines Guidelines for .NET Development

[ 19 ]

March 2009 Dennis Doomen

www.avivasolutions.nl blog.avivasolutions.nl

5 Performance Guidelines

AV1800 Clearly document if calling a member has a performance impact

If calling a member causes a performance impact such as involvement of unmanaged code, copies that are being

made, expensive calculations that are being performed, or network interaction, then clearly document that. This allows

to caller to explicitly cache the result of calling the member and prevent a potential performance issue.

Page 22: AvSol CSharp 3.0 Coding Guidelines

C# 3.0 Coding Guidelines Guidelines for .NET Development

[ 20 ]

March 2009 Dennis Doomen

www.avivasolutions.nl blog.avivasolutions.nl

6 Usage Guidelines

AV2201 Do use C# types instead of the types from the System namespace

For example: use object instead of Object, string instead of String, and int instead of Int32.

AV2205 Do properly name and use resources

The guidelines in this topic apply to localizable resources such as error messages and menu text.

Do use Pascal casing in resource keys.

Do provide descriptive rather than short identifiers. Keep them concise where possible, but don’t sacrifice

readability.

Do use only alphanumeric characters in naming resources.

AV2206 Don’t hardcode strings that are presented to end-users

Use resources instead.

AV2207 Don’t hardcode strings that change based on the deployment

Examples include connection strings, server addresses, etc. Use Resources, the ConnectionStrings property of

the ConfigurationManager class, or the Settings class generated by Visual Studio.

AV2210 Do build with the highest warning level

Configure the development environment to use Warning Level 4 for the C# compiler, and enable the option Treat

warnings as errors. This allows the compiler to enforce the highest possible code quality.

AV2211 Avoid suppressing specific compiler warnings

AV2215 Do properly fill the attributes of the AssemblyInfo.cs file

Ensure that the attributes for the company name, description, copyright statement, version, etc. are filled. One way to

ensure that version and other fields that are common to all assemblies have the same values, is to move the

corresponding attributes out of the AssemblyInfo.cs into a SolutionInfo.cs file that is shared by all projects

within the solution.

AV2216 Do always sign assemblies with a private key

Signing an assembly with a private key will give the assembly a strong name which enables the following benefits.

Malicious attempts to replace the assembly with another equally named assembly will fail.

Signed assemblies properly integrate with .NET security.

They can be deployed in the Global Assembly Cache.

Classes exposed in the assembly can be exposed to COM.

AV2220 Avoid LINQ for simple expressions

Rather than

var q = from item in items where item.Length > 0;

prefer using the extension methods from the System.Linq namespace.

var q = items.Where(i => i.Length > 0);

Page 23: AvSol CSharp 3.0 Coding Guidelines

C# 3.0 Coding Guidelines Guidelines for .NET Development

[ 21 ]

March 2009 Dennis Doomen

www.avivasolutions.nl blog.avivasolutions.nl

Since LINQ queries should be written out over multiple lines for readability, the second example is a bit more readable.

AV2221 Do use Lambda expressions instead of delegates

Lambda expressions have been introduced in C# 3.0 and provide a much more elegant alternative for anonymous

delegates. So instead of

Customer c = Array.Find(customers, delegate(Customer c)

{

return c.Name == “Tom”;

});

use an Lambda expression:

Customer c = Array.Find(customers, c => c.Name == “Tom”);

Or even better

var customer = customers.Where(c => c.Name == “Tom”);

Page 24: AvSol CSharp 3.0 Coding Guidelines

C# 3.0 Coding Guidelines Guidelines for .NET Development

[ 22 ]

March 2009 Dennis Doomen

www.avivasolutions.nl blog.avivasolutions.nl

7 Documentation Guidelines

AV2301 Do write comments and documentation in US English

AV2305 Do use XML tags for documenting types and members

Document all public types and member of types using the built-in XML comment functionality of Visual Studio.

Documenting your code allows Visual Studio to pop-up the documentation when your class is used somewhere else.

Furthermore, by properly documenting your classes, tools can generate professionally looking class documentation.

The XML elements in the following table are available for documenting a class or class member.

XML element Description

<summary> Short description of maximum two or three lines. This element is used to generate an

overview page of the members of a class.

<remarks> Provides additional details, including preconditions, special behaviour, the relation to

other members or classes.

<param> Describes the meaning of a method or constructor argument.

<returns> Describes the return value of a method.

<typeparam> Describes a type parameter for a generic type or method declaration to describe. Add

a tag for each type parameter of the generic type or method.

<value> Describes the type of the data a property accepts or returns.

These elements can also be used on classes and their members but are used to enrich the documentation.

XML element Description

<code> Marks a block of text as code.

<example> Specifies an example of how to use a method or other library member. This commonly

involves using the <code> tag.

<seealso> Adds an entry to the See Also section at the bottom of a documentation page.

<overloads> Provides a summary for multiple overloads of a method. Without this, the overview page

of a class will take the summary of the first overload.

<event> Indicates which events under which conditions will be raised by a method or property.

<exception> Specifies which exceptions can be thrown that a caller may catch.

<exclude/> Ensures that a member does not appear in generated documentation.

<include> Specifies to comments in another file that describe the types and members in your

source code. This is an alternative to placing documentation comments directly in your

source code file.

<permission> Documents the access of a member.

<preliminary> Indicates that the documentation is preliminary and may change in the near future.

<threadsafety> Describes how a class behaves in a multi-threaded environment.

Inline elements can be used within the contents of the elements from the preceding table.

Page 25: AvSol CSharp 3.0 Coding Guidelines

C# 3.0 Coding Guidelines Guidelines for .NET Development

[ 23 ]

March 2009 Dennis Doomen

www.avivasolutions.nl blog.avivasolutions.nl

XML element Description

<see> Creates a hyperlink to another member or type.

<paramref> Creates a reference to a <param> of the current member.

<typeparamref> Creates a reference to a <typeparam> of the current member.

<note> Creates a note block with distinct appearance.

AV2306 Do write XML documentation with the caller in mind

Write the documentation of your class with the class user in mind. Assume the user will not have access to the source

code and try to explain how to get the most out of the functionality of your class.

AV2307 Do write MSDN-style documentation

Following the MSDN on-line help style and word choice helps the developer to find its way through your documentation

more easily.

Tip The tool GhostDoc can generate a starting point for documenting code with a shortcut key.

AV2308 Do document preconditions

Properly document the preconditions for using a class or its members. Examples include:

Argument requirements: non-null, minimum length of an array, element type of an array, etc.

State/order related: what other members must be called first.

External dependencies: is a certain resource (network, file, etc) required?

AV2309 Do document post conditions

Document clearly whether a member returns null, an empty string, an empty array or something alike. To prevent

surprises for the developer, try to stay close to the .NET Framework philosophy.

AV2310 Do document the exceptions that a member can throw

Document the exceptions a member can throw (using the <exception> tag) and explain under which situations it may

throw this exception. Consider the .NET Framework online help as a good example of how to properly document this.

AV2315 Do use // for comments

AV2316 Do write comments that explain the purpose of a code block

Try to focus comments on the why and what of a code block and not the how. Avoid explaining the statements in

words, but instead, help the reader understand why you chose a certain solution or algorithm and what you are trying to

achieve. If applicable, also mention that you chose an alternative solution because you ran into a problem with the

obvious solution.

Tip

You can also define your own tags like <comment>. They will not be used yet, but can be helpful to add additional

comments.

Page 26: AvSol CSharp 3.0 Coding Guidelines

C# 3.0 Coding Guidelines Guidelines for .NET Development

[ 24 ]

March 2009 Dennis Doomen

www.avivasolutions.nl blog.avivasolutions.nl

8 Layout Guidelines

AV2401 Don’t put a using statement in a namespace

AV2402 Do order and group namespaces according the company

// Microsoft namespaces are first

using System;

using System.Collections;

using System.XML;

// Then any other namespaces in alphabetic order

using AvivaSolutions.Business;

using AvivaSolutions.Standard;

using Telerik.WebControls;

using Telerik.Ajax;

AV2403 Don’t define multiple namespaces in one file

A single file should contribute types to only a single namespace.

AV2405 Do place modifiers in a well-defined order

When multiple modifier keywords are needed in a type or member declaration, the modifiers should be placed in the

following order of appearance: public, protected, internal, private, partial, new, abstract, virtual,

override, sealed, static, readonly, extern, volatile, const.

AV2406 Order class members in a well-defined pattern.

Maintaining a common order allows other team members to find their way in your code more easily. In order of

appearance:

1. Private fields (in a region)

2. Public read-only static fields

3. Constructors and the Finalizer

4. Events

5. Properties

6. Other members grouped in a functional manner. Common groups include:

a. Control event handlers

b. Page lifecycle handlers

c. Interface implementations (in a #region)

7. Private properties

Private methods should be placed behind the public member in calling order. This prevents readers from having to

browse up and down through the code file.

AV2407 Be reluctant with #regions

Regions can be helpful, but can also hide to main purpose of a class. Therefore, use #regions only for:

Private fields (preferably in a Private Definitions region).

Control event handlers

Page lifecycle handlers

Page 27: AvSol CSharp 3.0 Coding Guidelines

C# 3.0 Coding Guidelines Guidelines for .NET Development

[ 25 ]

March 2009 Dennis Doomen

www.avivasolutions.nl blog.avivasolutions.nl

Nested classes

Helper classes (in the same file)

Interface implementations (only if the class contains other members)

Although not required, give the #endregion statement the same name as the #region to improve readability.

AV2410 Use empty lines wherever considered appropriate

See an empty line as a paragraph break in a text document. So statements or declarations that logically belong to each

other should be hold together. And remember, a text document with a paragraph break after each one or two

sentences is difficult to follow, so don’t overdo. Good candidates for an empty line include:

Between members

After the closing parentheses

Between unrelated code blocks

Around the #region keyword

Between the using statements of the same company.

AV2411 Don’t exceed a line length of 130 characters

AV2412 Do insert space after if, switch, while, for, foreach, catch, lock and using

AV2413 Do put parentheses on a new line

Always put { and } on new lines at the same level of indentation as the keyword they belong to.

if (someCondition)

{

Foo();

}

Exception To help distinct simple from more complex code, property getters and setters that only consist of a single

statement may be written in a more compact form. For example:

public string Name

{

get { return name; }

set

{

if ((name != null) && (name.Length > 0))

{

name = value;

}

}

}

Page 28: AvSol CSharp 3.0 Coding Guidelines

C# 3.0 Coding Guidelines Guidelines for .NET Development

[ 26 ]

March 2009 Dennis Doomen

www.avivasolutions.nl blog.avivasolutions.nl

9 Resources

1. LINQ Design Guidelines, Mircea Trofin

http://blogs.msdn.com/mirceat/archive/2008/03/13/linq-framework-design-guidelines.aspx

2. .NET Framework Design Guidelines, Brad Adams

http://blogs.msdn.com/brada/archive/tags/Framework+Design+Guidelines/default.aspx

3. Applying Domain-Driven Design and Patterns in C#, Jimmy Nielsen

http://www.jnsk.se/adddp/

4. The Developer Highway Code, Microsoft

http://msdn.microsoft.com/en-gb/security/aa473878.aspx

5. CodeBetter.com

http://codebetter.com/

6. Patterns & Practices guidance, Microsoft

http://msdn.microsoft.com/en-us/practices/bb969054.aspx

7. Liskop Substitution Principle

http://www.objectmentor.com/resources/articles/lsp.pdf

Page 29: AvSol CSharp 3.0 Coding Guidelines

C# 3.0 Coding Guidelines Guidelines for .NET Development

[ 27 ]

March 2009 Dennis Doomen

www.avivasolutions.nl blog.avivasolutions.nl

10 List of Code Analysis Rules

The table below lists the Visual Studio Code Analysis / FxCop rules that we at Aviva Solutions recommend for any serious

software development. Since generic and framework code requires a higher quality than for instance line-of-business applications,

we made a distinction between the two using the LOB and Fx (framework) columns.

Design Rules LOB Fx Notes CA1000 DoNotDeclareStaticMembersOnGenericTypes x x CA1001 TypesThatOwnDisposableFieldsShouldBeDisposable x x CA1002 DoNotExposeGenericLists x x CA1003 UseGenericEventHandlerInstances x x CA1004 GenericMethodsShouldProvideTypeParameter x x Factory methods always violate this rule CA1005 AvoidExcessiveParametersOnGenericTypes x x CA1006 DoNotNestGenericTypesInMemberSignatures x x CA1007 UseGenericsWhereAppropriate x x CA1008 EnumsShouldHaveZeroValue x x CA1009 DeclareEventHandlersCorrectly x x CA1010 CollectionsShouldImplementGenericInterface x x CA1011 ConsiderPassingBaseTypesAsParameters x x Often needs overruling if you want to enfore a

specific subtype CA1012 AbstractTypesShouldNotHaveConstructors x x CA1013 OverloadOperatorEqualsOnOverloadingAddAndSubtract x x CA1014 MarkAssembliesWithClsCompliant x Required to guarantee compliance with VB.NET CA1016 MarkAssembliesWithAssemblyVersion x x CA1017 MarkAssembliesWithComVisible x CA1018 MarkAttributesWithAttributeUsage x x CA1019 DefineAccessorsForAttributeArguments x x CA1020 AvoidNamespacesWithFewTypes x CA1021 AvoidOutParameters x x CA1023 IndexersShouldNotBeMultidimensional x x CA1024 UsePropertiesWhereAppropriate x x CA1025 ReplaceRepetitiveArgumentsWithParamsArray x x CA1026 DefaultParametersShouldNotBeUsed x x CA1027 MarkEnumsWithFlags x x CA1028 EnumStorageShouldBeInt32 x x CA1030 UseEventsWhereAppropriate x x CA1031 DoNotCatchGeneralExceptionTypes x x CA1032 ImplementStandardExceptionConstructors x x CA1033 InterfaceMethodsShouldBeCallableByChildTypes x x CA1034 NestedTypesShouldNotBeVisible x x CA1035 ICollectionImplementationsHaveStronglyTypedMembers x x CA1036 OverrideMethodsOnComparableTypes x x CA1038 EnumeratorsShouldBeStronglyTyped x x CA1039 ListsAreStronglyTyped x x CA1040 AvoidEmptyInterfaces x x CA1041 ProvideObsoleteAttributeMessage x x CA1043 UseIntegralOrStringArgumentForIndexers CA1044 PropertiesShouldNotBeWriteOnly x x CA1045 DoNotPassTypesByReference x x CA1046 DoNotOverloadOperatorEqualsOnReferenceTypes x x CA1047 DoNotDeclareProtectedMembersInSealedTypes x x CA1048 DoNotDeclareVirtualMembersInSealedTypes x x CA1049 TypesThatOwnNativeResourcesShouldBeDisposable x x CA1050 DeclareTypesInNamespaces x x CA1051 DoNotDeclareVisibleInstanceFields x x CA1052 StaticHolderTypesShouldBeSealed x x CA1053 StaticHolderTypesShouldNotHaveConstructors x x CA1054 UriParametersShouldNotBeStrings x x CA1055 UriReturnValuesShouldNotBeStrings x x CA1056 UriPropertiesShouldNotBeStrings x x CA1057 StringUriOverloadsCallSystemUriOverloads x x CA1058 TypesShouldNotExtendCertainBaseTypes x x CA1059 MembersShouldNotExposeCertainConcreteTypes x x CA1060 MovePInvokesToNativeMethodsClass x x CA1061 DoNotHideBaseClassMethods x x CA1062 ValidateArgumentsOfPublicMethods x x CA1063 ImplementIDisposableCorrectly x x CA1064 ExceptionsShouldBePublic x x

Page 30: AvSol CSharp 3.0 Coding Guidelines

C# 3.0 Coding Guidelines Guidelines for .NET Development

[ 28 ]

March 2009 Dennis Doomen

www.avivasolutions.nl blog.avivasolutions.nl

CA1065 DoNotRaiseExceptionsInUnexpectedLocations x x

Globalization Rules CA1300 SpecifyMessageBoxOptions o o Only if you need to handle right-to-left languages CA1301 AvoidDuplicateAccelerators x x CA1302 DoNotHardcodeLocaleSpecificStrings x x CA1304 SpecifyCultureInfo CA1305 SpecifyIFormatProvider CA1306 SetLocaleForDataTypes DataSets should not be used anymore CA1307 SpecifyStringComparison o o only if localization is important CA1308 NormalizeStringsToUppercase x x CA1309 UseOrdinalStringComparison x x

Interoperability Rules CA1400 PInvokeEntryPointsShouldExist o o Only if you use P/Invoke CA1401 PInvokesShouldNotBeVisible o o Only if you use P/Invoke CA1402 AvoidOverloadsInComVisibleInterfaces o o Only if you use P/Invoke CA1403 AutoLayoutTypesShouldNotBeComVisible o o Only if you use P/Invoke CA1404 CallGetLastErrorImmediatelyAfterPInvoke o o Only if you use P/Invoke CA1405 ComVisibleTypeBaseTypesShouldBeComVisible o o Only if you use P/Invoke CA1406 AvoidInt64ArgumentsForVB6Clients o o Only if you use P/Invoke CA1407 AvoidStaticMembersInComVisibleTypes o o Only if you use P/Invoke CA1408 DoNotUseAutoDualClassInterfaceType o o Only if you use P/Invoke CA1409 ComVisibleTypesShouldBeCreatable o o Only if you use P/Invoke CA1410 ComRegistrationMethodsShouldBeMatched o o Only if you use P/Invoke CA1411 ComRegistrationMethodsShouldNotBeVisible o o Only if you use P/Invoke CA1412 MarkComSourceInterfacesAsIDispatch o o Only if you use P/Invoke CA1413 AvoidNonpublicFieldsInComVisibleValueTypes o o Only if you use P/Invoke CA1414 MarkBooleanPInvokeArgumentsWithMarshalAs o o Only if you use P/Invoke CA1415 DeclarePInvokesCorrectly o o Only if you use P/Invoke CA2101 SpecifyMarshalingForPInvokeStringArguments o o Only if you use P/Invoke

Portability Rules CA1900 ValueTypeFieldsShouldBePortable o o Only if you use P/Invoke CA1901 PInvokeDeclarationsShouldBePortable o o Only if you use P/Invoke

Mobility Rules CA1600 DoNotUseIdleProcessPriority x x CA1601 DoNotUseTimersThatPreventPowerStateChanges o o

Naming Rules CA1700 DoNotNameEnumValuesReserved x x CA1701 ResourceStringCompoundWordsShouldBeCasedCorrectly x x CA1702 CompoundWordsShouldBeCasedCorrectly x x CA1703 ResourceStringsShouldBeSpelledCorrectly x x CA1704 IdentifiersShouldBeSpelledCorrectly x x CA1705 LongAcronymsShouldBePascalCased x x CA1706 ShortAcronymsShouldBeUppercase x x CA1707 IdentifiersShouldNotContainUnderscores x x CA1708 IdentifiersShouldDifferByMoreThanCase x x CA1709 IdentifiersShouldBeCasedCorrectly x x CA1710 IdentifiersShouldHaveCorrectSuffix x x CA1711 IdentifiersShouldNotHaveIncorrectSuffix x x CA1712 DoNotPrefixEnumValuesWithTypeName x x CA1713 EventsShouldNotHaveBeforeOrAfterPrefix x x CA1714 FlagsEnumsShouldHavePluralNames x x CA1715 IdentifiersShouldHaveCorrectPrefix X x CA1716 IdentifiersShouldNotMatchKeywords X x CA1717 OnlyFlagsEnumsShouldHavePluralNames X x CA1718 AvoidLanguageSpecificTypeNamesInParameters X x CA1719 ParameterNamesShouldNotMatchMemberNames X x CA1720 AvoidTypeNamesInParameters/IdentifiersShouldNotContainTyp

eNames X x

CA1721 PropertyNamesShouldNotMatchGetMethods X x CA1722 IdentifiersShouldNotHaveIncorrectPrefix X x CA1724 TypeNamesShouldNotMatchNamespaces X x CA1725 ParameterNamesShouldMatchBaseDeclaration X x CA1726 UsePreferredTerms X x

Page 31: AvSol CSharp 3.0 Coding Guidelines

C# 3.0 Coding Guidelines Guidelines for .NET Development

[ 29 ]

March 2009 Dennis Doomen

www.avivasolutions.nl blog.avivasolutions.nl

Performance Rules CA1800 DoNotCastUnnecessarily X x CA1801 ReviewUnusedParameters X x CA1802 UseLiteralsWhereAppropriate X x CA1804 RemoveUnusedLocals X x CA1805 DoNotInitializeUnnecessarily X x CA1806 DoNotIgnoreMethodResults X x CA1807 AvoidUnnecessaryStringCreation X x CA1809 AvoidExcessiveLocals X x CA1810 InitializeReferenceTypeStaticFieldsInline Far fetched CA1811 AvoidUncalledPrivateCode X x CA1812 AvoidUninstantiatedInternalClasses X x CA1813 AvoidUnsealedAttributes X x CA1814 PreferJaggedArraysOverMultidimensional X x CA1815 OverrideEqualsAndOperatorEqualsOnValueTypes X x CA1816 DisposeMethodsShouldCallSuppressFinalize/CallGCSuppressFi

nalizeCorrectly X x

CA1817 DoNotCallPropertiesThatCloneValuesInLoops X x CA1818 DoNotConcatenateStringsInsideLoops X x CA1819 PropertiesShouldNotReturnArrays X x CA1820 TestForEmptyStringsUsingStringLength X x CA1821 RemoveEmptyFinalizers X x CA1822 MarkMembersAsStatic X x CA1823 AvoidUnusedPrivateFields X x CA1824 MarkAssembliesWithNeutralResourcesLanguage X x

Security Rules CA2100 ReviewSqlQueriesForSecurityVulnerabilities X x Use a O/R Mapper instead CA2102 CatchNonClsCompliantExceptionsInGeneralHandlers CA2103 ReviewImperativeSecurity X x CA2104 DoNotDeclareReadOnlyMutableReferenceTypes X x CA2105 ArrayFieldsShouldNotBeReadOnly X x CA2106 SecureAsserts x CA2107 ReviewDenyAndPermitOnlyUsage x CA2108 ReviewDeclarativeSecurityOnValueTypes x CA2109 ReviewVisibleEventHandlers X x CA2110 SecureGetObjectDataOverrides X x CA2111 PointersShouldNotBeVisible O o Only if you use P/Invoke CA2112 SecuredTypesShouldNotExposeFields x CA2114 MethodSecurityShouldBeASupersetOfType x CA2115 CallGCKeepAliveWhenUsingNativeResources O o Only if you use P/Invoke CA2116 AptcaMethodsShouldOnlyCallAptcaMethods x CA2117 AptcaTypesShouldOnlyExtendAptcaBaseTypes x CA2118 ReviewSuppressUnmanagedCodeSecurityUsage x CA2119 SealMethodsThatSatisfyPrivateInterfaces X x CA2120 SecureSerializationConstructors x CA2121 StaticConstructorsShouldBePrivate X x Is already checked by the compiler CA2122 DoNotIndirectlyExposeMethodsWithLinkDemands x CA2123 OverrideLinkDemandsShouldBeIdenticalToBase x CA2124 WrapVulnerableFinallyClausesInOuterTry x CA2126 TypeLinkDemandsRequireInheritanceDemands x CA2127 SecurityTransparentAssembliesShouldNotContainSecurity

CriticalCode x

CA2128 SecurityTransparentCodeShouldNotAssert x CA2129 SecurityTransparentCodeShouldNotReferenceNonpublicSecurity

CriticalCode x

Usage Rules CA2200 RethrowToPreserveStackDetails x x CA2201 DoNotRaiseReservedExceptionTypes x x CA2202 DoNotDisposeObjectsMultipleTimes x x CA2204 LiteralsShouldBeSpelledCorrectly x x CA2205 UseManagedEquivalentsOfWin32Api x x CA2207 InitializeValueTypeStaticFieldsInline x x CA2208 InstantiateArgumentExceptionsCorrectly x x CA2210 AssembliesShouldHaveValidStrongNames x x CA2211 NonConstantFieldsShouldNotBeVisible x x CA2212 DoNotMarkServicedComponentsWithWebMethod x x CA2213 DisposableFieldsShouldBeDisposed x x CA2214 DoNotCallOverridableMethodsInConstructors x x Always violated by NHibernate entities CA2215 DisposeMethodsShouldCallBaseClassDispose x x

Page 32: AvSol CSharp 3.0 Coding Guidelines

C# 3.0 Coding Guidelines Guidelines for .NET Development

[ 30 ]

March 2009 Dennis Doomen

www.avivasolutions.nl blog.avivasolutions.nl

CA2216 DisposableTypesShouldDeclareFinalizer x x CA2217 DoNotMarkEnumsWithFlags x x CA2218 OverrideGetHashCodeOnOverridingEquals x x CA2219 DoNotRaiseExceptionsInExceptionClauses6 x x CA2220 FinalizersShouldCallBaseClassFinalizer x x Is automatically done by the C# compiler CA2221 FinalizersShouldBeProtected x x Is automatically done by the C# compiler CA2222 DoNotDecreaseInheritedMemberVisibility x x CA2223 MembersShouldDifferByMoreThanReturnType x x CA2224 OverrideEqualsOnOverloadingOperatorEquals x x CA2225 OperatorOverloadsHaveNamedAlternates o o Only if you target other languages than C# and

VB.NET CA2226 OperatorsShouldHaveSymmetricalOverloads x x CA2227 CollectionPropertiesShouldBeReadOnly x x CA2228 DoNotShipUnreleasedResourceFormats x x CA2229 ImplementSerializationConstructors x x CA2230 UseParamsForVariableArguments x x CA2231 OverloadOperatorEqualsOnOverridingValueTypeEquals x x CA2232 MarkWindowsFormsEntryPointsWithStaThread x x CA2233 OperationsShouldNotOverflow x x CA2234 PassSystemUriObjectsInsteadOfStrings x x CA2235 MarkAllNonSerializableFields x x CA2236 CallBaseClassMethodsOnISerializableTypes x x CA2237 MarkISerializableTypesWithSerializable x x CA2238 ImplementSerializationMethodsCorrectly x x CA2239 ProvideDeserializationMethodsForOptionalFields x x CA2240 ImplementISerializableCorrectly x x CA2241 ProvideCorrectArgumentsToFormattingMethods x x CA2242 TestForNaNCorrectly x x CA2243 AttributeStringLiteralsShouldParseCorrectly x x

Maintainability Rules CA1500 VariableNamesShouldNotMatchFieldNames x x CA1501 AvoidExcessiveInheritance x x CA1502 AvoidExcessiveComplexity x x CA1504 ReviewMisleadingFieldNames x x CA1505 AvoidUnmaintainableCode x x CA1506 AvoidExcessiveClassCoupling x x

Reliability Rules CA2000 DisposeObjectsBeforeLosingScope x x CA2001 AvoidCallingProblematicMethods x x CA2002 DoNotLockOnObjectsWithWeakIdentity x x CA2003 DoNotTreatFibersAsThreads x x CA2004 RemoveCallsToGCKeepAlive x x CA2006 UseSafeHandleToEncapsulateNativeResources x x