C# Coding Standards and Naming Conventions

We will discuss C# coding conventions and best practices.

Object Name Notation Length Plural Prefix Suffix Abbreviation Char Mask Underscores
Namespace name PascalCase 128 Yes Yes No No [A-z][0-9] No
Class name PascalCase 128 No No Yes No [A-z][0-9] No
Constructor name PascalCase 128 No No Yes No [A-z][0-9] No
Method name PascalCase 128 Yes No No No [A-z][0-9] No
Method arguments camelCase 128 Yes No No Yes [A-z][0-9] No
Local variables camelCase 50 Yes No No Yes [A-z][0-9] No
Constants name PascalCase 50 No No No No [A-z][0-9] No
Field name Public PascalCase 50 Yes No No Yes [A-z][0-9] No
Field name Private _camelCase 50 Yes No No Yes _[A-z][0-9] Yes
Properties name PascalCase 50 Yes No No Yes [A-z][0-9] No
Delegate name PascalCase 128 No No Yes Yes [A-z] No
Enum type name PascalCase 128 Yes No No No [A-z] No

1. Do use PascalCasing for class names and method names:

CSHARP
public class ClientActivity
{
  public void ClearStatistics()
  {
    //...
  }
  public void CalculateStatistics()
  {
    //...
  }
}

Why: consistent with the Microsoft's .NET Framework and easy to read.

2. Do use camelCasing for method arguments and local variables:

CSHARP
public class UserLog
{
  public void Add(LogEvent logEvent)
  {
    int itemCount = logEvent.Items.Count;
    // ...
  }
}

Why: consistent with the Microsoft's .NET Framework and easy to read.

3. Do not use Hungarian notation or any other type identification in identifiers

CSHARP
// Correct
int counter;
string name;    
// Avoid
int iCounter;
string strName;

Why: consistent with the Microsoft's .NET Framework and Visual Studio IDE makes determining types very easy (via tooltips). In general, you want to avoid type indicators in any identifier.

4. Do not use Screaming Caps for constants or readonly variables:

CSHARP
// Correct
public const string ShippingType = "DropShip";
// Avoid
public const string SHIPPINGTYPE = "DropShip";

Why: consistent with the Microsoft's .NET Framework. Caps grab too much attention.

5. Use meaningful names for variables. The following example uses seattleCustomers for customers who are located in Seattle:

CSHARP
var seattleCustomers = from customer in customers
  where customer.City == "Seattle" 
  select customer.Name;

Why: consistent with the Microsoft's .NET Framework and easy to read.

6. Avoid using Abbreviations. Exceptions: abbreviations commonly used as names, such as Id, Xml, Ftp, Uri.

// Correct
UserGroup userGroup;
Assignment employeeAssignment;     
// Avoid
UserGroup usrGrp;
Assignment empAssignment; 
// Exceptions
CustomerId customerId;
XmlDocument xmlDocument;
FtpHelper ftpHelper;
UriPart uriPart;

<div data-code-id="__CODE_BLOCK_5__"></div>
csharp  
HtmlHelper htmlHelper;
FtpTransfer ftpTransfer, fastFtpTransfer;
UIControl uiControl, nextUIControl;

<div data-code-id="__CODE_BLOCK_6__"></div>
csharp 
// Correct
public DateTime clientAppointment;
public TimeSpan timeLeft;    
// Avoid
public DateTime client_Appointment;
public TimeSpan time_Left; 
// Exception (Class field)
private DateTime _registrationDate;

<div data-code-id="__CODE_BLOCK_7__"></div>
csharp
// Correct
string firstName;
int lastIndex;
bool isSaved;
string commaSeparatedNames = String.Join(", ", names);
int index = Int32.Parse(input);
// Avoid
String firstName;
Int32 lastIndex;
Boolean isSaved;
string commaSeparatedNames = string.Join(", ", names);
int index = int.Parse(input);

<div data-code-id="__CODE_BLOCK_8__"></div>
csharp 
var stream = File.Create(path);
var customers = new Dictionary();
// Exceptions
int index = 100;
string timeSheet;
bool isCompleted;

<div data-code-id="__CODE_BLOCK_9__"></div>
csharp 
public class Employee
{
}
public class BusinessLocation
{
}
public class DocumentCollection
{
}

<div data-code-id="__CODE_BLOCK_10__"></div>
csharp     
public interface IShape
{
}
public interface IShapeCollection
{
}
public interface IGroupable
{
}

<div data-code-id="__CODE_BLOCK_11__"></div>
csharp 
// Located in Task.cs
public partial class Task
{
}
// Located in Task.generated.cs
public partial class Task
{
}

<div data-code-id="__CODE_BLOCK_12__"></div>
csharp 
// Examples
namespace Company.Technology.Feature.Subnamespace
{
}
namespace Company.Product.Module.SubModule
{
}
namespace Product.Module.Component
{
}
namespace Product.Layer.Module.Group
{
}

<div data-code-id="__CODE_BLOCK_13__"></div>
csharp 
// Correct
class Program
{
  static void Main(string[] args)
  {
    //...
  }
}

<div data-code-id="__CODE_BLOCK_14__"></div>
csharp 
// Correct
public class Account
{
  public static string BankName;
  public static decimal Reserves;      
  public string Number { get; set; }
  public DateTime DateOpened { get; set; }
  public DateTime DateClosed { get; set; }
  public decimal Balance { get; set; }     
  // Constructor
  public Account()
  {
    // ...
  }
}

<div data-code-id="__CODE_BLOCK_15__"></div>
csharp 
// Correct
public enum Color
{
  Red,
  Green,
  Blue,
  Yellow,
  Magenta,
  Cyan
} 
// Exception
[Flags]
public enum Dockings
{
  None = 0,
  Top = 1,
  Right = 2, 
  Bottom = 4,
  Left = 8
}

<div data-code-id="__CODE_BLOCK_16__"></div>
csharp 
// Don't
public enum Direction : long
{
  North = 1,
  East = 2,
  South = 3,
  West = 4
} 
// Correct
public enum Direction
{
  North,
  East,
  South,
  West
}

<div data-code-id="__CODE_BLOCK_17__"></div>
csharp     
// Don't
public enum CoinEnum
{
  Penny,
  Nickel,
  Dime,
  Quarter,
  Dollar
} 
// Correct
public enum Coin
{
  Penny,
  Nickel,
  Dime,
  Quarter,
  Dollar
}

<div data-code-id="__CODE_BLOCK_18__"></div>
csharp 
// Don't
[Flags]
public enum DockingsFlags
{
  None = 0,
  Top = 1,
  Right = 2, 
  Bottom = 4,
  Left = 8
}
// Correct
[Flags]
public enum Dockings
{
  None = 0,
  Top = 1,
  Right = 2, 
  Bottom = 4,
  Left = 8
}

<div data-code-id="__CODE_BLOCK_19__"></div>
csharp 
// Correct
public class BarcodeReadEventArgs : System.EventArgs
{
}

<div data-code-id="__CODE_BLOCK_20__"></div>
csharp 
public delegate void ReadBarcodeEventHandler(object sender, ReadBarcodeEventArgs e);

<div data-code-id="__CODE_BLOCK_21__"></div>
csharp 
// Avoid
private void MyFunction(string name, string Name)
{
  //...
}

<div data-code-id="__CODE_BLOCK_22__"></div>
csharp
public void ReadBarcodeEventHandler(object sender, ReadBarcodeEventArgs e)
{
  //...
}

<div data-code-id="__CODE_BLOCK_23__"></div>
csharp 
// Correct
public class BarcodeReadException : System.Exception
{
}

<div data-code-id="__CODE_BLOCK_24__"></div>
csharp 
// Correct
public static bool IsNullOrEmpty(string value) {
    return (value == null || value.Length == 0);
}

<div data-code-id="__CODE_BLOCK_25__"></div>
csharp
// Method
public void DoSomething(string foo, int bar) 
{
...
}

// Avoid
DoSomething("someString", 1);
// Correct
DoSomething(foo: "someString", bar: 1);

Why: consistent with the Microsoft's .NET Framework and easy to read. In Named Arguments, we do not need to pass the parameters in order as defined on method definition, so we can pass the arguments in any order on method calling.

#Official Reference

  1. MSDN General Naming Conventions
  2. DoFactory C# Coding Standards and Naming Conventions
  3. MSDN Naming Guidelines
  4. MSDN Framework Design Guidelines
  5. Common C# Coding Conventions
  6. Github C# Coding Style