Beruflich Dokumente
Kultur Dokumente
Author
Subject:
Florin Olariu
Target:
Coding Guidelines
.NET developers
CODING GUIDELINES
HISTORY
Version
1.
Date
Name
Comment
14/01/201
5
Florin Olariu
2.
3.
4.
5.
6.
7.
8.
9.
PAGE 1/42
Centric IT Solutions
Coding guidelines
Author
Subject:
Florin Olariu
Target:
Coding Guidelines
.NET developers
CONTENTS
History...............................................................................................................1
Contents............................................................................................................2
1
Introduction..............................................................................................7
1.1 Purpose.....................................................................................................7
1.2 How to get started....................................................................................7
Code reviews.............................................................................................7
2.1 Changesets...............................................................................................7
2.2 Code comments........................................................................................7
3.5.1
General................................................................................................................................................8
3.5.2
Naming guidelines.............................................................................................................................10
3.5.3
Context specification.........................................................................................................................10
3.5.4
Implementation guidelines.................................................................................................................11
Design guidelines...................................................................................12
4.1 Classes....................................................................................................12
4.1.1
4.1.2
4.1.3
4.1.4
4.1.5
It should be possible to treat a derived object as if it were a base class object .........13
PAGE 2/42
Centric IT Solutions
Coding guidelines
Author
Subject:
Florin Olariu
Target:
Coding Guidelines
.NET developers
4.1.6
4.1.7
4.1.8
4.1.9
4.2 Interfaces................................................................................................14
4.2.1
4.2.2
4.2.3
4.3 Methods...................................................................................................15
4.3.1
4.3.2
4.3.3
4.4 Properties................................................................................................15
4.4.1
4.4.2
4.4.3
String, list and collection properties should never return a null reference .................16
4.4.4
4.4.5
4.4.6
Consider replacing properties using primitive types to use rich value objects ..........16
4.5 Fields.......................................................................................................16
4.5.1
Use a public static readonly field to define predefined value objects ..........................16
4.6 Events.....................................................................................................17
4.6.1
4.6.2
4.6.3
4.6.4
Dont pass null as the sender parameter when raising an event ......................................17
4.7 Exceptions...............................................................................................18
PAGE 3/42
Centric IT Solutions
Coding guidelines
Author
Subject:
Florin Olariu
Target:
Coding Guidelines
.NET developers
4.7.1
Throw exceptions rather than returning some kind of status value ................................18
4.7.2
4.7.3
4.7.4
4.8 Generics..................................................................................................18
4.8.1
Dont add extension methods to the same namespace as the extended class ...............19
Maintainability guidelines....................................................................19
5.1.1
5.1.2
5.1.3
5.1.4
5.1.5
5.1.6
5.1.7
Name a source file to the logical function of the partial type .........................................20
5.1.8
5.1.9
5.1.10
5.1.11
5.1.12
5.1.13
5.1.14
Use an enumeration instead of a list of strings if the list of values is finite ...........23
5.1.15
5.1.16
5.1.17
AV1535 Add a block after all flow control keywords, even if it is empty ...............23
PAGE 4/42
Centric IT Solutions
Coding guidelines
Author
Subject:
Florin Olariu
Target:
Coding Guidelines
.NET developers
5.1.18
Always add a default block after the last case in a switch statement ........................24
5.1.19
5.1.20
5.1.21
5.1.22
5.1.23
5.1.24
5.1.25
5.1.26
5.1.27
5.1.28
5.1.29
5.1.30
5.1.31
5.1.32
5.1.33
Performance guidelines........................................................................28
6.1.1
6.1.2 Consider using First, FirstOrDefault(p=> ) When looking for the first item in a
list that matches a predicate....................................................................................................................29
7
Naming guidelines.................................................................................29
7.1 Projects...................................................................................................29
7.2 Casing.....................................................................................................29
7.3 Case sensitivity.......................................................................................30
7.4 Abbreviations..........................................................................................30
7.5 Namespaces............................................................................................31
7.5.1
7.6 Types.......................................................................................................31
PAGE 5/42
Centric IT Solutions
Coding guidelines
Author
Subject:
Florin Olariu
Target:
Coding Guidelines
.NET developers
7.6.1
7.6.2
7.6.3
7.7 Members..................................................................................................32
7.7.1
7.7.2
7.7.3
Name an identifier according to its meaning and not its type .........................................32
7.7.4
7.7.5
Avoid short names or names that can be mistaken for other names ...............................32
7.7.6
7.7.7
7.8 Events.....................................................................................................33
7.8.1
7.8.2
7.8.3
7.8.4
Layout guidelines...................................................................................34
8.1 Use a common layout..............................................................................34
8.2 Order and group namespaces according to the company .......................34
8.3 Place members in a well-defined order ..................................................35
PAGE 6/42
Centric IT Solutions
Coding guidelines
Author
Subject:
Florin Olariu
Target:
Coding Guidelines
.NET developers
INTRODUCTION
1.1 PURPOSE
The purpose of this document is to provide a standardized way of coding for C#
developers within Centric IT Solutions from within the Solution Engineering. It contains
rules, guidelines, recommendations for proper usage of the .NET Framework, proper
usage of object oriented design, code layout, naming conventions.
Install StyleCop 4.7 (you can download it here). The StyleCop settings for the
project will be under source control, so you dont have to worry about configuring
it.
Install Resharper 7.1 (you can download it here). The Resharper settings for the
project will be under source control, so you dont have to worry about configuring
it.
The CodeAnalysis settings for the project will be under source control, so you dont
have to worry about configuring it.
CODE REVIEWS
2.1 CHANGESETS
Make sure your changesets are small and task / user story related. Dont work on
multiple user stories at a time and check in as often as possible, preferably when
youve finished a task, in order to be easier to follow your changes during the code
review process.
Make sure you write a comprehensive checkin message, which explains what
youve done and how youve approached the task at hand.
Link your changeset to both the user story and task youve worked on if it is
possible.
Centric IT Solutions
Coding guidelines
Author
Subject:
Florin Olariu
Target:
Coding Guidelines
.NET developers
before the reviewer gets a chance to look at it and it is also a way of defending the
reasoning and methods behind the code changes youve made.
3.1 SOLID
SOLID stands for:
Single Responsibility
Open-Closed
Liskov Substitution
Interface Segregation
Dependency Inversion
The five principles if used judiciously should result in code that is easier to maintain by
being highly decoupled and allow the changing of specific implementation details without
(or with less) friction.
Like every principle/guideline in software development the SOLID principles need to be
understood but not used blindly. It is very easy to over architect a solution by being too
dogmatic about the use of any guideline. You do however, need to be aware when a
violation of SOLID principles occurs and make that decision based on its context and
merits.
Read more about it here.
3.2 DRY
Dont Repeat Yourself (a.k.a. DRY), requires you to rigorously remove duplication in your code base.
3.3 KISS
Keep It Simple Stupid (a.k.a. KISS), a funny way of saying that the simplest solution is more than sufficient.
3.4 YAGNI
You Aint Gonna Need It (a.k.a. YAGNI), which tells you to create a solution for the current problem rather than
the ones you think will happen later on (since when can you predict the future?).
PAGE 8/42
Centric IT Solutions
Coding guidelines
Author
Florin Olariu
Subject:
Target:
Coding Guidelines
.NET developers
PAGE 9/42
Centric IT Solutions
Coding guidelines
Author
Subject:
Florin Olariu
Target:
Coding Guidelines
.NET developers
Test-driven
developmenta
birds-eye view.
Notice the spiral
nature of the process:
write test, write
code, refactor, write
next test. It shows
the incremental
nature of TDD: small
steps lead to a
quality end result.
Project
Class
PAGE
10/42
Centric IT Solutions
Coding guidelines
Author
Subject:
Florin Olariu
Target:
Coding Guidelines
.NET developers
class ExceptionHandlerSpecs
Code example:
public class CurrencyDetailsScreenSpecs
{
public virtual void Initialize()
{
// common initialize code for all the contexts
}
// returns our system under test
private CurrencyDetailsScreen CreateSUT()
{
// returns our system under test
}
[TestClass]
public class When_chain_is_changed_and_the_new_chain_does_not_have_main_currency : Curren
cyDetailsScreenSpecs
{
[TestInitialize]
public override void Initialize()
{
// common code for our context
}
[TestMethod]
public void Should_have_factor_be_Multiply()
{
// assert our condition
PAGE
11/42
Centric IT Solutions
Coding guidelines
Author
Florin Olariu
Subject:
Target:
Coding Guidelines
.NET developers
}
[TestMethod]
public void Should_set_Exchange_Rate_to_1()
{
// assert our condition
}
}
[TestClass]
public class When_other_context : CurrencyDetailsScreenSpecs
{
/* ... */
}
}
PAGE
12/42
Centric IT Solutions
Coding guidelines
Author
Subject:
Florin Olariu
Target:
Coding Guidelines
.NET developers
Remove test duplication. As with other code duplication makes tests harder to
maintain. Test code is Production Code.
Make sure tests are isolated. One test should never influence the result of
another. If this is the case tests fill fail due to changes or failure of another test,
making the test brittle.
Dont test more than 1 thing per unit test. Testing only one thing per test will
make sure a test only breaks if that item changed and avoids a cascade of failing
tests.
Avoid multiple asserts, related to the previous guideline.
Avoid multiple asserts must also apply for mocking methods like
Assert.MethodWasCalled.
Please test also that something was not happen in a specific branch. Do not test
only what is happening.
Dont have your tests be a copy of your class to test.
DESIGN GUIDELINES
4.1 CLASSES
PAGE
13/42
Centric IT Solutions
Coding guidelines
Author
Florin Olariu
Subject:
Target:
Coding Guidelines
.NET developers
Note If you create a class representing a primitive type you can greatly simplify it usage
by making it immutable.
Centric IT Solutions
Coding guidelines
Author
Florin Olariu
Subject:
Target:
Coding Guidelines
.NET developers
{
Console.WriteLine("Printing Book");
}
}
public class PocketBook : Book
{
public new void Print()
{
Console.WriteLine("Printing PocketBook");
}
}
This will cause the following behavior which is not something you normally expect from
class hierarchies.
PocketBook 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 through
the derived class.
PAGE
15/42
Centric IT Solutions
Coding guidelines
Author
Florin Olariu
Subject:
Target:
Coding Guidelines
.NET developers
An object should not expose any other classes it depends on because callers may misuse
that exposed property or method to access the object behind it. By doing so, you allow
calling code to become coupled to the class you are using, and thereby limiting the
chance you can easily replace it in a future stage.
Note Using a class that is designed using the Fluent Interface pattern does seem to
violate this rule, but is in reality something else. It simply returns itself so that method
chaining is allowed. Exception Inversion of Control or Dependency Injection frameworks
often require you to expose a dependency as a public property. As long as this property is
not used for anything else than dependency injection, then it is not considered a
violation.
4.2 INTERFACES
4.2.1 AN INTERFACE SHOULD BE SMALL AND FOCUSED
Interfaces should have a clear name explaining the purpose or role of that interface
within the system. Do not combine many vaguely related members on the same
interface, just because they were all on the same class. Separate the members based on
the responsibility of those members so that callers only need to call or implement the
interface related to a particular task. This rule is more commonly known as the Interface
Segregation Principle.
PAGE
16/42
Centric IT Solutions
Coding guidelines
Author
Subject:
Florin Olariu
Target:
Coding Guidelines
.NET developers
4.3 METHODS
4.3.1 USE A METHOD INSTEAD OF A PROPERTY
If the operation returns a different result each time it is called, even if the parameters didnt change.
For example, the NewGuid method returns a different value each time it is called.
If the operation causes a side effect such as changing some internal state not directly related the
property. Note that populating an internal cache or implementing lazy loading is a good exception.
PAGE
17/42
Centric IT Solutions
Coding guidelines
Author
Florin Olariu
Subject:
Target:
Coding Guidelines
.NET developers
4.4 PROPERTIES
4.4.1 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.
PAGE
18/42
Centric IT Solutions
Coding guidelines
Author
Florin Olariu
Subject:
Target:
Coding Guidelines
.NET developers
A classic example of this is the HttpContext.Current property, part of ASP.NET. Its very
difficult to unit test a class like that without using a very intelligent and intrusive mocking
framework such as TypeMock Isolator. Many see the HttpContext class as a source for a
lot of ugly code. In fact, the testing guideline Isolate the Ugly Stuff often refers to this
class.
4.5 FIELDS
4.5.1 USE A PUBLIC STATIC READONLY FIELD TO DEFINE PREDEFINED
VALUE OBJECTS
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. 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
}
}
4.6 EVENTS
4.6.1 ALWAYS CHECK AN EVENT HANDLER DELEGATE FOR NULL
An event that has no subscribers is null, so before invoking, always make sure that the
delegate list represented by the event variable is not null. Furthermore, to prevent
PAGE
19/42
Centric IT Solutions
Coding guidelines
Author
Florin Olariu
Subject:
Target:
Coding Guidelines
.NET developers
Tip You can prevent the delegate list from being empty altogether. Simply assign an
empty delegate like this:
event EventHandler<NotifyEventArgs> Notify = delegate {};
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.
PAGE
20/42
Centric IT Solutions
Coding guidelines
Author
Florin Olariu
Subject:
Target:
Coding Guidelines
.NET developers
event data parameter when raising an event. If there is no event data, pass
EventArgs.Empty instead of null.
4.7 EXCEPTIONS
4.7.1 THROW EXCEPTIONS RATHER THAN RETURNING SOME KIND OF
STATUS VALUE
A code base that uses return values for reporting the success or failure tends to have
nested if-statements sprinkled all over the code. Quite often, a caller forgets to check
the return value anyhow. Structured exception handling has been introduced to allow you
to throw exceptions and catch or replace exceptions at a higher layer. In most systems it
is quite common to throw exceptions whenever an unexpected situations occurs.
4.8 GENERICS
4.8.1 USE GENERIC CONSTRAINTS IF APPLICABLE
PAGE
21/42
Centric IT Solutions
Coding guidelines
Author
Florin Olariu
Subject:
Target:
Coding Guidelines
.NET developers
Instead of casting to and from the object type in generic types or methods, use where
contraints or the as operator to specify the exact characteristics of the generic
parameter. 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;
}
}
PAGE
22/42
Centric IT Solutions
Coding guidelines
Author
Florin Olariu
Subject:
Target:
Coding Guidelines
.NET developers
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.
MAINTAINABILITY GUIDELINES
Double negatives are more difficult to grasp than simple expressions, and people tend to
read over the double negative easily.
PAGE
23/42
Centric IT Solutions
Coding guidelines
Author
Florin Olariu
Subject:
Target:
Coding Guidelines
.NET developers
Do:
using System.Collections.Generic;
var list = new List<string>();
If you do need to prevent name clashing, use a using directive to assign an alias:
using Label = System.Web.UI.WebControls.Label;
Centric IT Solutions
Coding guidelines
Author
Florin Olariu
Subject:
Target:
Coding Guidelines
.NET developers
Dont 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, dont
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.
5.1.10
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 myfoo = MyFactoryMethod.Create("arg");
// Not obvious what base-class or
// interface to expect. Also difficult
// to refactor if you can't search for
PAGE
25/42
Centric IT Solutions
Coding guidelines
Author
Subject:
Florin Olariu
Target:
Coding Guidelines
.NET developers
// the class
Do:
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>();
5.1.11
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.
5.1.12
FAVOR OBJECT AND COLLECTION INITIALIZERS OVER
SEPARATE STATEMENTS
Instead of:
var startInfo = new ProcessStartInfo(myapp.exe);
startInfo.StandardOutput = Console.Output;
startInfo.UseShellExecute = true;
5.1.13
It is usually bad style to compare a bool-type expression to true or false. For example:
PAGE
26/42
Centric IT Solutions
Coding guidelines
Author
Subject:
Florin Olariu
while
while
while
while
Target:
Coding Guidelines
.NET developers
5.1.14
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.
5.1.15
DONT CHANGE A LOOP VARIABLE INSIDE A FOR OR FOREACH
LOOP
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.
}
}
5.1.16
A method that nests loops is more difficult to understand than one with only a single loop.
In fact, in most cases having nested loops can be replaced with a much simpler LINQ
query that uses the from keyword twice or more to join the data.
5.1.17
AV1535 ADD A BLOCK AFTER 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)
PAGE
27/42
Centric IT Solutions
Coding guidelines
Author
Florin Olariu
Subject:
Target:
Coding Guidelines
.NET developers
{
Foo();
}
else
{
Bar();
}
}
5.1.18
ALWAYS 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);
}
}
5.1.19
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
{
PAGE
28/42
Centric IT Solutions
Coding guidelines
Author
Subject:
Florin Olariu
Target:
Coding Guidelines
.NET developers
5.1.20
One entry, one exit is a sound principle and keeps control flow readable. However, if the
method is very small and complies with guideline 4.1.1 then multiple return statements
may actually improve readability over some central Boolean flag that is updated at
various points.
5.1.21
DONT 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
{
pos = false;
}
Write:
bool pos = (val > 0); // initialization
5.1.22
AV1546 PREFER CONDITIONAL STATEMENTS INSTEAD OF
SIMPLE IF-ELSE CONSTRUCTS
For example, instead of:
string result;
if (someString != null)
{
result = someString;
}
else
{
result = Unavailable;
PAGE
29/42
Centric IT Solutions
Coding guidelines
Author
Florin Olariu
Subject:
Target:
Coding Guidelines
.NET developers
}
return result;
Write:
return someString ?? Unavailable;
5.1.23
ENCAPSULATE COMPLEX EXPRESSIONS IN A METHOD OR
PROPERTY
Consider the following example:
if (member.HidesBaseClassMember && (member.NodeType != NodeType.InstanceInitializer))
{
// do something
}
In order to understand what this expression is about, you need to analyze its exact details
and all the possible outcomes. Obviously, you could add an explanatory comment on top
of it, but it is much better to replace this complex expression with a clearly named
method:
if (NonConstructorMemberUsesNewKeyword(member))
{
// do something
}
private bool NonConstructorMemberUsesNewKeyword(Member member)
{
return
(member.HidesBaseClassMember &&
(member.NodeType != NodeType.InstanceInitializer)
}
You still need to understand the expression if you are modifying it, but the calling code is
now much easier to grasp.
5.1.24
CALL THE MOST OVERLOADED METHOD FROM OTHER
OVERLOADS
This guideline only applies to overloads that are intended for providing optional
arguments. Consider for example the following code snippet:
public class MyString
{
PAGE
30/42
Centric IT Solutions
Coding guidelines
Author
Subject:
Florin Olariu
Target:
Coding Guidelines
.NET developers
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. Also notice that the parameters with the same name
should appear in the same position in all overloads.
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.
5.1.25
The only valid reason for using C# 4.0s optional parameters is to replace the example
from rule 4.1.24 with a single method like:
public virtual int IndexOf(string phrase, int startIndex = 0, int count = 0)
{
return someText.IndexOf(phrase, startIndex, count);
}
If the optional parameter is a reference type then it can only have a default value of null.
But since strings, lists and collections should never be null, you must use overloaded
methods instead.
PAGE
31/42
Centric IT Solutions
Coding guidelines
Author
Florin Olariu
Subject:
Target:
Coding Guidelines
.NET developers
Note The default values of the optional parameters are stored at the caller side. As such,
changing the default value without recompiling the calling code will not apply the new
default value property.
5.1.26
C# 4.0s named parameters have been introduced to make it easier to call COM
components that are known for offering tons of optional parameters. If you need named
parameters to improve the readability of the call to a method, that method is probably
doing too much and should be refactored.
The only exception where named parameters improve readability is when a constructor
that yields a valid object is called like this:
Person person = new Person
(
firstName: "John",
lastName: "Smith",
dateOfBirth: new DateTime(1970, 1, 1)
);
5.1.27
If you end up with a method with more than three parameters, use a structure or class for
passing multiple parameters such as explained in the Specification design pattern. In
general, the fewer the number of parameters, the easier it is to understand the method.
Additionally, unit testing a method with many parameters requires many scenarios to
test.
5.1.28
Ref and out parameters make code less understandable and therefore may introduce
bugs. Prefer returning compound objects instead.
5.1.29
A flag parameter based on a bool is not self-explanatory. Consider the following method
signature:
public Customer CreateCustomer(bool platinumLevel) {}
PAGE
32/42
Centric IT Solutions
Coding guidelines
Author
Florin Olariu
Subject:
Target:
Coding Guidelines
.NET developers
On first sight this signature seems perfectly fine, but when calling this method you will
lose this purpose completely:
Customer customer = CreateCustomer(true);
Often, a method taking such a flag is doing more than one thing and needs to be
refactored into two or more methods. An alternative solution is to replace the flag with an
enumeration.
5.1.30
Never use a parameter as a convenient variable for storing temporary state. Even though
the type of your temporary variable may be the same, the name usually does not reflect
the purpose of the temporary variable.
5.1.31
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.
5.1.32
Never check-in code that is commented-out, but instead use a work item tracking system
to keep track of some work to be done. Nobody knows what to do when they encounter a
block of commented-out code. Was it temporarily disabled for testing purposes? Was it
copied as an example? Should I delete it?
5.1.33
CONSIDER ABSTRACTING AN EXTERNAL DEPENDENCY OR 3RD
PARTY COMPONENT
If your code relies on some kind of external class, service or UI control, consider wrapping
that dependency in a lightweight wrapper that only exposes the members that are really
used. Such a wrapper smoothens the changes required when replacing that dependency
with another, but can also be used to hide any undesired behavior or bugs that you dont
have influence on.
PERFORMANCE GUIDELINES
PAGE
33/42
Centric IT Solutions
Coding guidelines
Author
Florin Olariu
Subject:
Target:
Coding Guidelines
.NET developers
NAMING GUIDELINES
7.1 PROJECTS
Projects should be named using the following pattern:
<CompanyName>.<ProjectName>.<ComponentName>
7.2 CASING
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:
Example: PascalCase
CamelCase:
The first letter of an identifier is lowercase and the first letter of each subsequent
concatenated word is capitalized. For example:
Example: camelCase
UpperCase:
All letters in the identifier are capitalized. Use this convention only for identifiers that
consist of two or fewer letters. For example:
PAGE
34/42
Centric IT Solutions
Coding guidelines
Author
Florin Olariu
Subject:
Target:
Coding Guidelines
.NET developers
System.IO
System.Web.UI
Capitalization usage:
Identifier
Class
e
al
Enum Type
Cas
Pasc
Example
MyClass
Pasc
StatusType
Pasc
HighStatus
Pasc
MyEvent
Pasc
MyException
Pasc
RedValue
Pasc
IDisposable
Pasc
ToString
Notes
al
Enum Values
al
Event
al
Exception Class
al
Read-Only Static
Field
Interface
al
al
Method
Always begins
with prefix I
al
Namespace
Pasc
al
Parameter
Ca
Centric.DataAc
cess
typeName
mel
Property
Pasc
BackColor
Ca
redValue
Ca
redValue
Pasc
RedValue
al
Private Instance
Field
Protected Instance
Field
Public Instance
Field
mel
mel
al
PAGE
35/42
Centric IT Solutions
Rarely used. A
property is preferred
to using a protected
instance field
Rarely used. A
property is preferred
to using a public
instance field.
OLARIU, FLORINOLARIU, FLORIN
Coding guidelines
Author
Subject:
Florin Olariu
Target:
Coding Guidelines
.NET developers
7.4 ABBREVIATIONS
Dont 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 q. Use index or query instead.
Exceptions Use well-known abbreviations that are widely accepted or well-known within
the domain you work. For instance, use UI instead of UserInterface.
7.5 NAMESPACES
7.5.1 NAME NAMESPACES ACCORDING A WELL-DEFINED PATTERN
All namespaces should be named according to the pattern
<Company>.(<Product >)[.<Feature>][.<Subnamespace>]
For instance: Microsoft.WindowsMobile.DirectX.
Note Dont use the same name for a namespace and a type in that namespace. For
example, dont use Debug for a namespace name and also provide a class named Debug
in the same namespace.
7.6 TYPES
7.6.1 NAME TYPES USING NOUNS, NOUN PHRASES OR ADJECTIVE
PHRASES
Bad examples include SearchExamination (a page for searching for examinations),
Common (does not end with a noun, and does not explain its purpose) and SiteSecurity
(although the name is technically okay, it does not say anything about its purpose).
Good examples include BusinessBinder, SmartTextBox, or EditableSingleCustomer.
PAGE
36/42
Centric IT Solutions
Coding guidelines
Author
Subject:
Florin Olariu
Target:
Coding Guidelines
.NET developers
Dont include terms like Utility or Helper in classes. Classes with a name like that are
usually static classes and are introduced without considering the object-oriented
principles.
7.7 MEMBERS
7.7.1 DONT INCLUDE NUMBERS IN IDENTIFIERS
PAGE
37/42
Centric IT Solutions
Coding guidelines
Author
Subject:
Florin Olariu
Target:
Coding Guidelines
.NET developers
Numbers in names of fields, variables or members are very rarely needed. In fact, in most
cases they are a lazy excuse for not defining a clear and intention-revealing name.
Use semantically interesting names rather than language-specific keywords for type names. For
example, GetLength is a better name than GetInt.
Dont use terms like Enum, Class or Struct in a name.
Identifiers that refer to an array or collection should have a plural name.
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
PAGE
38/42
Centric IT Solutions
Coding guidelines
Author
Subject:
Florin Olariu
Target:
Coding Guidelines
.NET developers
example, if you have an enumeration named CacheLevel, a property that returns one of its values
can also be named CacheLevel.
7.8 EVENTS
7.8.1 USE A VERB OR VERB PHRASE TO NAME AN EVENT
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;
PAGE
39/42
Centric IT Solutions
Coding guidelines
Author
Florin Olariu
Subject:
Target:
Coding Guidelines
.NET developers
LAYOUT GUIDELINES
Centric IT Solutions
Coding guidelines
Author
Florin Olariu
Subject:
Target:
Coding Guidelines
.NET developers
Put the entire LINQ statement on one line, or start each keyword at the same
indentation, like this:
var query = from product in products where product.Price > 10 select product;
or
var query =
from product in products
where product.Price > 10
select product;
Add braces around every comparison condition, but dont add braces around a
singular condition. For example:
if (!string.IsNullOrEmpty(str) && (str != new))
Add an empty line between multi-line statements, between members, after the
closing parentheses, between unrelated code blocks, around the #region keyword,
and between the using statements of different companies.
Static fields
Constants
Read-only fields
Constructors and destructors
Public properties
Protected properties
Private properties
PAGE
41/42
Centric IT Solutions
Coding guidelines
Author
Florin Olariu
Subject:
Target:
Coding Guidelines
.NET developers
PAGE
42/42
Centric IT Solutions