Code Standard
Code Standard
Code Standard
Below are our C# coding standards, naming conventions, and best practices. Use these in your own projects and/or adjust these to your own needs.
douse PascalCasing for abbreviations 3 characters or more (2 chars are both uppercase)
HtmlHelper htmlHelper; FtpTransfer ftpTranfer; UIControl uiControl; Why: consistent with the Microsoft's .NET Framework. Caps would grap visually too much attention.
do notuse Underscores in identifiers. Exception: you can prefix private static variables
with an underscore. // Correct public DateTime clientAppointment; public TimeSpan timeLeft; // Avoid public DateTime client_Appointment; public TimeSpan time_Left; // Exception private DateTime _registrationDate; Why: consistent with the Microsoft's .NET Framework and makes code more natural to read (without 'slur'). Also avoids underline stress (inability to see underline).
douse predefined type names instead of system type names like Int16, Single, UInt64, etc
// Correct string firstName; int lastIndex; bool isSaved; // Avoid String firstName; Int32 lastIndex; Boolean isSaved; Why: consistent with the Microsoft's .NET Framework and makes code more natural to read.
douse implicit type var for local variable declarations. Exception: primitive types (int, string,
double, etc) use predefined names. var stream = File.Create(path); var customers = new Dictionary<int?, Customer>();
// Exceptions int index = 100; string timeSheet; bool isCompleted; Why: removes clutter, particularly with complex generic types. Type is easily detected with Visual Studio tooltips.
public interface IShape { } public interface IShapeCollection { } public interface IGroupable { } Why: consistent with the Microsoft's .NET Framework.
doname source files according to their main classes. Exception: file names with partial classes
reflect their source or purpose, e.g. designer, generated, etc. // Located in Task.cs public partial class Task { //... } // Located in Task.generated.cs public partial class Task { //... } Why: consistent with the Microsoft practices. Files are alphabetically sorted and partial classes remain adjacent.
dodeclare all member variables at the top of a class, with static variables at the very top.
// Correct public class Account { public static string BankName; public static decimal Reserves; public public public public string Number {get; set;} DateTime DateOpened {get; set;} DateTime DateClosed {get; set;} decimal Balance {get; set;}
// Constructor public Account() { // ... } } Why: generally accepted practice that prevents the need to hunt for variable declarations.
Table of Contents
1. Introduction.......................................................................................................................................... 1 2. Style Guidelines.................................................................................................................................... 2 2.1 Tabs & Indenting................................................................................................................................ 2 2.2 Bracing............................................................................................................................................... 2 2.3 Commenting........................................................................................................................................ 2 2.3.1 Documentation Comments............................................................................................................. 2 2.3.2 Comment Style............................................................................................................................. 3 2.4 Spacing............................................................................................................................................... 3 2.5 Naming............................................................................................................................................... 4 2.6 Naming Conventions............................................................................................................................ 4 2.6.1 Interop Classes............................................................................................................................. 4 2.7 File Organization................................................................................................................................. 5
1. Introduction
First, read the .NET Framework Design Guidelines. Almost all naming conventions, casing rules, etc., are spelled out in this document. Unlike the Design Guidelines document, you should treat this document as a set of suggestedguidelines. These generally do not effect the customer view so they are not required.
2. Style Guidelines
2.1 Tabs & Indenting
Tab characters (\0x09) should not be used in code. All indentation should be done with 4 space characters.
2.2 Bracing
Open braces should always be at the beginning of the line after the statement that begins the block. Contents of the brace should be indented by 4 spaces. For example:
case statements should be indented from the switch statement like this:
switch (someExpression) { case 0: DoSomething(); break; case 1: DoSomethingElse(); break; case 2: { int n = 1; DoAnotherThing(n); } break; }
Braces should never be considered optional. Even for single statement blocks, you should always use braces. This increases code readability and maintainability.
for (int i=0; i<100; i++) { DoSomething(i); }
It is suggested that all control structures (if, while, for, etc.) use braces, but it is not required.
2.4 Commenting
Comments should be used to describe intention, algorithmic overview, and/or logical flow. It would be ideal, if from reading the comments alone, someone other than the author could understand a functions intended behavior and general operation. While there are no minimum comment requirements and certainly some very small routines need no commenting at all, it is hoped that most routines will have comments reflecting the programmers intent and approach.
However, it is common that you would want to move the XML documentation to an external file for that, use the <include> tag.
public class Foo { /// <include file='doc\Foo.uex' path='docs/doc[@for="Foo.MyMethod"]/*' /> /// public void MyMethod(int bar) { } }
UNDONE there is a big doc with all the comment tags we should be using where is that?
2.5 Spacing
Spaces improve readability by decreasing code density. Here are some guidelines for the use of space characters within code:
Do use a single space after a comma between function arguments. Right: Wrong:
Do not use a space after the parenthesis and function arguments Right: Wrong:
Do not use spaces between a function name and parenthesis. Right: Wrong:
Do use a single space before and after comparison operators Right: Wrong:
2.6 Naming
Follow all .NET Framework Design Guidelines for both internal and external members. Highlights of these include:
Do not use Hungarian notation Do not use a prefix for member variables (_, m_, s_, etc.). If you want to distinguish between local and member variables you should use this. in C# and Me. in VB.NET. Do use camelCasing for member variables Do use camelCasing for parameters Do use camelCasing for local variables Do use PascalCasing for function, property, event, and class names Do prefix interfaces names with I Do not prefix enums, classes, or delegates with any letter
The reasons to extend the public rules (no Hungarian, no prefix for member variables, etc.) is to produce a consistent source code appearance. In addition a goal is to have clean readable source. Code legibility should be a primary goal.
SafeNativeMethods Has suppress unmanaged code attribute. These methods are safe and can be used fairly safely and the caller isnt needed to do full security reviews even though no stack walk will be performed.
[DllImport(user32)] internal static extern void FormatHardDrive(string driveName); } [SuppressUnmanagedCode] class UnsafeNativeMethods { private UnsafeNativeMethods() {}
[DllImport(user32)] internal static extern void CreateFile(string fileName); } [SuppressUnmanagedCode] class SafeNativeMethods { private SafeNativeMethods() {} [DllImport(user32)] internal static extern void MessageBox(string text); }
All interop classes must be private, and all methods must be internal. In addition a private constructor should be provided to prevent instantiation.
For example, I would expect to find the public class System.Windows.Forms.Control in System\Windows\Forms\Control.cs
Classes member should be alphabetized, and grouped into sections (Fields, Constructors, Properties, Events, Methods, Private interface implementations, Nested types) Using statements should be inside the namespace declaration.
namespace MyNamespace { using System; public class MyClass : IFoo { // fields int foo; // constructors public MyClass() { } // properties public int Foo { get { } set { } } // events public event EventHandler FooChanged { add { } remove { } }
// methods void DoSomething() { } void FindSomethind() { } //private interface implementations void IFoo.DoSomething() { DoSomething(); } // nested types class NestedType { } } }
Introduction
Developers always love to fight about coding standards. But it is very vital to follow coding standards to achieve consistency throughout the project or code. All should be of the same mind that conventions are very influential. I will show some good practices that I have learned during my professional years, those are lower level but very important for all levels.
Quick Test
Let us demonstrate a FizzBuzz example. The FizzBuzz test is to write a program that goes through the numbers 1 to 100. For every multiple of 3, the program should output "Fizz" and for every multiple of 5 it should output "Buzz". If both above conditions are met it should output "FizzBuzz". If none of the above conditions are met, it should just output the number.
Example 1:
Collapse | Copy Code
public void Test() { for (int i = 1; i < 101; i++) { if (i % 3 == 0 && i % 5 == 0) { Console.WriteLine("FizzBuzz"); } else if (i % 3 == 0) { Console.WriteLine("Fizz"); } else if (i % 5 == 0) { Console.WriteLine("Buzz"); } else { Console.WriteLine(i); } }
public void Check() { for (int i = 1; i <= 100; i++) { string output = ""; if (i % 3 == 0) { output = "Fizz"; } if (i % 5 == 0) { output = output + "Buzz"; } if (output == "") { output = i.ToString(); } Console.WriteLine(output); } }
What do you think now ? Do we need to make the code even better? Ok, let me help to make it better. Naming thing is one of the hardest job we have as a software developer. Because we spend a lot of time naming things, there are so many things to name properties, methods, classes, files, projects etc. We should spend some energies for naming things because names can be meanings. Adding meaning to code is readability all about.
Collapse | Copy Code
public void DoFizzBuzz() { for (int number = 1; number <= 100; number++) { var output = GetFizzBuzzOutput(number); Console.WriteLine(output); } } private static string GetFizzBuzzOutput(int number) { string output = string.Empty; if (number%3 == 0) { output = "Fizz"; } if (number%5 == 0) { output += "Buzz"; } if(string.IsNullOrEmpty(output)) { output = number.ToString(); } return output; }
What do you think now? Is this better than previous examples ? Is it more readable?
From my point of view a better should carried out the following characteristics:
Code that is easy to write , modify and extend Code that is clean and talks/convey meaning Code that has values and cares about quality So, write with the human reader in mind while satisfying the needs of the machine to the degree necessary.
First you have to read other peoples code and figure out what is good and what is bad within that code. What makes you easy to understand and what makes you feel more complicated. Then apply those things to your own code. Finally you need sometime, some experience and you need some practice to improve the readability of your code. It is very hard but obvious to implement standards in any software company, through methods like Trainings, Peer Code Reviews, Introducing automated code review tools, etc. The most popular tools are as follows:
FxCop is a tool that performs static code analysis of .NET code. It provides hundreds of rules that perform various types of analysis. StyleCop is an open source project that analyzes C# source code to enforce a set of style and consistency rules. It can be run from inside of Visual Studio or integrated into an MSBuild project. StyleCop has also been integrated into many third-party development tools. JetBrains ReSharper is a renowned productivity tool that makes Microsoft Visual Studio a much better IDE. Thousands of .NET developers worldwide wonder how theyve ever lived without ReSharpers code inspections, automated code refactoring, blazing fast navigation, and coding assistance.
According to Wikipedia "Coding conventions are a set of guidelines for a specific programming language that recommend programming style, practices and methods for each aspect of a piece program written in this language. These conventions usually cover file organization, indentation, comments, declarations, statements, white space, naming conventions, programming practices, programming principles, programming rules of thumb, architectural best practices, etc. These are guidelines for software structural quality. Software programmers are highly recommended to follow these guidelines to help improve the readability of their source code and make software maintenance easier. Coding conventions are only applicable to the human maintainers and peer reviewers of a software project. Conventions may be formalized in a documented set of rules that an entire team or company follows, or may be as informal as the habitual coding practices of an individual. Coding conventions are not enforced by compilers. As a result, not following some or all of the rules has no impact on the executable programs created from the source code." You should be able to tell the difference between a property, local variable, method name, class name etc. because they use different capitalization conventions. These type of conventions has values. You will be able to get lots of guidelines and conventions over internet. So find a convention or build your own and stick with it. The source of the following (Design Guidelines for Developing Class Libraries) was developed by the Microsoft special interest group. I just made some addons.
Capitalization Conventions
Below are some examples of our C# coding standards, naming conventions, and best practices. Use these according to your own needs.
Pascal Casing
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.
Camel Casing
The first letter of an identifier is lowercase and the first letter of each subsequent concatenated word is capitalized.
C# Coding Conventions C# Coding Guidelines C# Coding Standards and Best Programming Practices C# Coding Standards and Naming Conventions I am providing some basic level examples below but as I already mentioned, find a good convention that fits for you and stick with it. Do use PascalCasing for class names and method names.
public class Product { public void GetActiveProducts() { //... } public void CalculateProductAdditinalCost() { //... } }
Do declare all member variables at the top of a class, with static variables at the very top.
Collapse | Copy Code
public class Product { public static string BrandName; public string Name{get; set;} public DateTime DateAvailable {get; set;} public Product() { // ... } }
They help you transfer knowledge across projects They help you learn code more quickly on a new project. They emphasize relationships among related items. You should write readable code because it helps other people to read your code. Naming thing is one of the hardest job we have as a software developer. Because we spend a lot of time naming things, there are so many things to name properties, methods, classes, files, projects etc. We should spend some energies for naming things because names can be meanings. Adding meaning to code is readability all about. So it will help you better sleep at night.
Or According to Martins definition :"THERE SHOULD NEVER BE MORE THAN ONE REASON FOR A CLASS TO CHANGE."
Why was it important to separate these two responsibilities into separate classes? Because each responsibility is an axis of change. When the requirements change, that change will be manifest through a change in responsibility amongst the classes. If a class assumes more than one responsibility, then there will be more than one reason for it to change. If a class has more then one responsibility, then the responsibilities become coupled. Changes to one responsibility may impair or inhibit the class ability to meet the others. This kind of coupling leads to fragile designs that break in unexpected ways when changed.
comments. I am suggesting because method names are more affective than comments. Most of the comments are meaningless noise. Let us check comments below:
Collapse | Copy Code
//ensure that we are not exporting //deleted products if(product.IsDeleted && !product.IsExported ) { ExportProducts = false; } // This is a for loop that prints the 1 million times for (int i = 0; i < 1000000; i++) { Console.WriteLine(i); }
If we name the method like CancelExportForDeletedProducts() instead of comments what will happen? So, method names are more affective than comments. Methods execute and they are real. But comment is good for some cases like, when visual studio will take comments for creating an API documentation and those comments are different, you can use "///" for those comments so that other developers can get intelligence of API or Library. I am not telling you that avoid comment is a must for all the times. According to Kent's oral tradition point goes more to large-scale comments about how the whole thing works, not to individual method comments. If comment is trying to describe the purpose/intentions then it is wrong. If you look at thickly commented code, you will notice that most of those comments are there because the code is bad. Please read the following books for further detail:
Professional Refactoring in C# and ASP.NET by Danijel Arsenovski "Refactoring: Improving the Design of Existing Code" by Martin Fowler, Kent Beck, John Brant, William Opdyke, don Roberts
a real time-saver. You can use the Visual Studio extract method which will track which variables are passed to a new method, which are returned by the methods return value as output parameters. Using ReSharper
For more detail on each step, please navigate the MSDN link. According to Refactoring: Improving the Design of Existing Code by Martin Fowler, Kent Beck (Contributor), John Brant (Contributor), William Opdyke, don Roberts
"Extract Method is one of the most common refactoring I do. I look at a method that is too long or look at code that needs a comment to understand its purpose. I then turn that fragment of code into its own method. I prefer short, well-named methods for several reasons. First, it increases the chances that other methods can use a method when the method is finely grained. Second, it allows the higher-level methods to read more like a series of comments. Overriding also is easier when the methods are finely grained. It does take a little getting used to if you are used to seeing larger methods. And small methods really work only when you have good names, so you need to pay attention to naming. People sometimes ask me what length I look for in a method. To me length is not the issue. The key is the semantic distance between the method name and the method body. If extracting improves clarity, do it, even if the name is longer than the code you have extracted."
//avoid public void Checkout(string shippingName, string shippingCity, string shippingSate, string shippingZip, string billingName, string billingCity, string billingSate, string billingZip) { }
Collapse | Copy Code
Complex expression have some meaning behind them it is just hidden by those multiple expressions. We can encapsulate the complex expression into that object by using a property. That code will be easier to read.
If you notice the code you will find a variable that was declared but never used. Normally if we build the project we will get a warning and we can run our project without any error. But we should remove warning as much as possible. So setup your build to treat warning as Errors like the following steps:
//avoid if(product.Price>15) { return false; } else if(product.IsDeleted) { return false; } else if(!product.IsFeatured) { return false; } else if() { //..... } return true;
Collapse | Copy Code
//DO var isValid = true; if(product.Price>15) { isValid= false; } else if(product.IsDeleted) { isValid= false; } else if(!product.IsFeatured) { isValid= false; } return isValid;
You can imagine 4 exit points scattered around 20- 30 lines of code. That makes you more harder to understand and see what is happening inside the method and what will execute and when will execute. I got too many responses, some agreeing but mostly disagreeing that it was a good "standard" to enforce. To find out the potentiality I did some unit testing and found that for complex method that have multiple exit points usually have a set of tests for each of those paths.
Collapse | Copy Code
if( BADFunction() == true) { // expression if( anotherFunction() == true ) { // expression return true; } else { //error } } else
if( !GoodFunction()) { // error. return false } // expression if( !GoodFunction2()) { //error. return false; } // more expression return true;
Assertion
An assertion is code thats used during developmentusually a routine or macrothat allows to check itself as it runs. True means everything is operating as expected. False means it has detected an unexpected error in the code. An assertion usually takes two arguments: a Boolean expression that describes the assumption thats supposed to be true and a message to display if it isnt. Assertions are especially useful in large, complicated and in high reliability system. Example: If a system assumes that there will be maximum 100,000 user records, the system might contain an assertion that the number of records is less than or equal to 100,000. So assertion will be silent within that range. If it encounters more than that records, it will loudly assert that there is an error in the program.
those too. If the loop contains complex computations, get out your calculator and manually check the calculations.
Conclusion
It is obvious to implement standards in any software company according to organizational behavior, project nature, and domain. So I would like to repeat "Find a convention and stick with it". If you think I missed any prominent guideline, please leave that in the comments section. Ill try to include that in the main post. Coding For Fun.