C# Coding standards

  • use PascalCasing for class names and method names
public class ClientActivity 
{ 
    public void ClearStatistics() 
    { 
        //... 
    } 

    public void CalculateStatistics() 
    { 
        //... 
    } 
} 
  • use camelCasing for method arguments and local variables.
public class UserLog 
{ 
   public void Add(LogEvent logEvent) 
   { 
    var itemCount = logEvent.Items.Count; 

    // ... 
   } 
} 
  • do not use Hungarian notation or any other type identification in identifiers (except interfaces)
// Correct 
int counter; 
string name; 

// Avoid 
int iCounter; 
string strName;

The Visual Studio IDE makes determining types very easy (via tooltips). In general you want to avoid type indicators in any identifier (Exception: Interfaces)

  • do not use SCREAMING CAPS for constants or read-only variables
// Correct 
public static const string ShippingType = "DropShip"; 

// Avoid 
public static const string SHIPPINGTYPE = "DropShip"; 
  • 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; 
  • use PascalCasing for abbreviations 3 characters or more (2 chars are both uppercase)
HtmlHelper htmlHelper; 
FtpTransfer ftpTransfer; 
UIControl uiControl; 

The type here is Pascal, but the field is camelNotation.
  • do not use Underscores in identifiers. Prefix private member variables with an underscore.
// Correct 
public DateTime clientAppointment; 
public TimeSpan timeLeft; 

// Avoid 
public DateTime client_Appointment; 
public TimeSpan time_Left; 

// Exception 
private DateTime registrationDateStore; 
  • use 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; 
  • use implicit type var for local variable declarations
var stream = File.Create(path); 
var customers = new Dictionary(); 
var index = 100; 
var greeting = "hello"; 
var isCompleted = true;
  • prefix interfaces with the letter I. Interface names are noun (phrases) or adjectives
public interface IShape 
{ 

} 

public interface IGroupable 
{ 

} 
  • name source files according to their main classes
// Located in Task.cs 
public partial class Task 
{ 
   //... 
} 
  • organize namespaces with a clearly defined structure. Generally namespaces should reflect the folder hierarchy within a project
  • vertically align curly braces
class Program 
{ 
   static void Main(string[] args) 
   { 

   } 
} 
  • declare all member variables at the top of a class, with static variables at the very top. Exception, keep backing variables with their property.
public class Account 
{ 
   private int AgeStore;
   private string NameStore;

   public string Number {get; set;} 

   // Constructor 
   public Account() 
   { 
       // ... 
   } 
} 
  • use singular names for enums and plural for bit field enums.
// 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 
} 
  • do not explicitly specify a type of an enum or values of enums (except bit fields and where the value is required)
// Don't 
public enum Direction : long 
{ 
   North = 1, 
   East = 2, 
   South = 3, 
   West = 4 
} 

// Correct 
public enum Direction 
{ 
   North, 
   East, 
   South, 
   West 
} 

// Correct
public enum Temperatures
{
   Freezing = 32,
   Boiling = 212
}

// Exception
[Flags]
enum Days
{
    None      = 0b_0000_0000, // 0
    Sunday    = 0b_0000_0001, // 1
    Monday    = 0b_0000_0010, // 2
    Tuesday   = 0b_0000_0100, // 4
    Wednesday = 0b_0000_1000, // 8
    Thursday  = 0b_0001_0000, // 16
    Friday    = 0b_0010_0000, // 32
    Saturday  = 0b_0100_0000  // 64 
}
class MyClass
{
    Days meetingDays = Days.Tuesday | Days.Thursday;
}
  • Name global styles and static resources with their functional purpose instead of (for example) a color name
// Don't
    <Application.Resources>
        <ResourceDictionary>
           <Color x:Key="Red">#FFDC0A0A</Color>
        </ResourceDictionary>
    </Application.Resources>

//Correct
    <Application.Resources>
        <ResourceDictionary>
           <Color x:Key="Error">#FFDC0A0A</Color>
        </ResourceDictionary>
    </Application.Resources>
  • If your line of code is greater than 80, chop it to two or more lines except where essential.
  • Prefer Switch statements to multiple nested if statements
// Don't
if (...)
{
    if (...)
    {
    ...
    }
}
else if(...)
{
    ...
}

// Correct
switch(...)
case 1:
  ...
  break;
case 2:
   ...
   Break;
  • Use braces with conditionals, for loops, etc.
// Correct
   if (condition)
   {
       action;
   }
   
// Don't
   if(conditioin) 
      action;
  • Where possible prefer switch expressions over switch statements
// wrong
switch(foo)
{
    case 1:
      x = 50;
      break;
    case 2:
      x = 100
      break;
     default:
       x = 0;
       break
}

// Correct
foo switch
{
    1 => 50;
    2 => 100;
    _ => 0;
}
  • enable nullable references and treat these warnings as errors
#nullable enable
Person? person;  //etc.
  • use null conditional (?.) operator rather than if statements for null
// wrong
if (a != null)
{
    if (b != null)
    {
        return c.name;
    }
}

// right
return a?.b?.c.name;
  • use null coalescing (??) operator rather than if statements for null
// wrong
if (a != null)
{
    if (b != null)
    {
        return c.name;
    }
    {
        else return string.empty;
    }
}
else
{
    return string.empty;
}

// right
return a?.b?.c.name ?? string.empty;
  • refer SetValue & Lambda expressions for properties (inherit from BaseViewModel)
// wrong
private string _property;
public string Property
{
    get { return _property; }
    set
    {
        _property = value;
        OnPropertyChanged;
    }
}

// right
private string _property;
public string Property
{
  get => _property;
  set => SetValue(ref _property, value);
}

// SetValue is created in the base class and handles checking for changed values and calls to INotifyPropertyChanged.
  • declare and define commands in one statement in the ViewModel
public ICommand MyCommand =>
    new Command( async ( ) => await OnMyCommand( ) )
  • Do not place all backing variables together — put them with their properties
// Wrong
private string _prop1;
private int _prop2;
private int _prop3;

public string Prop1
{ ... }
public int Prop2
{...}
public int Prop3
{...}

// Correct
private string _prop1;
public string Prop1
{ ... }

private int _prop2;
public int Prop2
{...}

private int _prop3;
public int Prop3
{...}
  • Treat Warnings As Errors
  • Use “TODO” sparingly, and check the TODO list often