C# Standards

Naming conventions

Prefix variable type bools with ‘is’, ‘has’ etc. Phrase it as a question.

Why? – Improves readability and prevents confusing variable usage.

// Correct
bool isFinished = false;
bool hasAccess = true;

// Don't
bool finished = false;
bool access = true;

Don’t use Hungarian notation in identifiers.

Why? – Hinders readability and is bad practice.

// Correct
int counter;
string name;

// Don’t
int iCounter;
string strName;

Don’t use Screaming Caps for constants or readonly variables.

Why? – Consistent with the Microsoft’s .NET Framework

// Correct
const string ShippingType = "DropShip";

// Don’t
const string SHIPPINGTYPE = "DropShip";

Use meaningful names for variables, functions, etc.

Why? – Avoids confusion and makes code easier to read/understand.

// Correct
int customerNumber = 1234;
            
// Don't
int num = 1234;

Automatically enforced (Only in .cs Files)

Use PascalCasing for class names, function names and member variable.

Why? – Improves readability and identification of member level variables.

public class ClientActivity
{
    public static string BankName;

    public void ClearStatistics()
    {
        // ...
    }

    public void CalculateStatistics()
    {
        // ...
    }
}

Use camelCasing for function arguments and local variables.

Why? – Improves readability and identification of local level variables.

Exception – If the variable begins with an acronym then it doesn’t need to be camelCase (e.g., MFAData which stands for Multi Factor Authentication Data would be acceptable)

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

Prefix interfaces with the letter ‘I’.

Why? – Consistent with the Microsoft’s .NET Framework and makes interfaces easy to identify.

public interface IShape
{
    // ...
}

Formatting

Vertically align curly braces.

Why? – This makes it easy to see what code belongs to what function with a quick glance.

// Correct
if (condition)
{
    action;
}

// Don't
if (condition)
{
    action;
}

// Don't
if (condition) { action; }

Always use braces with conditionals, for loops, etc.

Why? – Without the braces it is too easy to accidentally add a second line thinking it is included in the if/loop etc., when it is not. Also improves readability.

// Correct
if (condition)
{
    action;
}

// Don't
if (condition)
    action;

Declare all member at the top of their class together.

Why? – Prevents the need to search for variable declarations throughout class.

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()
    {
        // ...
    }
}

Practices

Use explicit type for all variable declarations instead of implicit (var).

Why? – You should always know the variable type you’re working with and declare it.

// Correct
int index = 100;
string greeting = "hello";
bool isCompleted = true;

// Don't
var index = 100;
var greeting = "hello";
var isCompleted = true;

Check for null values before using an object reference.

Why? – Avoids surprise null reference exceptions; improves error handling.

public void Something(Object object)
{
    if (object != null)
    {
        // ...
    }
}

Use string interpolation.

Why? – Improves readability and is more concise.

// Correct  
string details = $"{test.Name}, you are welcome, Your Id is {test.Id}_emp";

// Don't 
string details = string.Format("{0}, you are welcome, Your Id is {1}", test.Name, test.Id + "_emp");

// Don't 
string details = test.name + ", you are welcome, Your Id is " + test.Id + "_emp";

Always use the ‘using’ keyword when working with disposable types.

Why? – It automatically disposes the object when program flow leaves the scope.  

using (FileStream fs = File.Create(path))
{
    // ...
}

Functions should only have one purpose, not multiple.

Why? – Keeps code structure simple and organized.

// Correct
SaveAddress(address);
SendEmail(address, email);

void SaveAddress(string address)
{
    // ...
}

void SendEmail(string address, string email)
{
    // ...
}

// Don't
SaveAddressAndSendEmail(address, email);

void SaveAddressAndSendEmail(string address, string email)
{
    // ...
}

If statements should test for success and the else should contain the failure. Otherwise when making a decision that doesn’t contain a clear success/fail path use positive logic flow.

Why? – Keeps code structure consistent and easy to read/navigate.

// Do This
myObject = await CallAPI(myObject);
if(myObject.ErrorMessage == "")
{
    // This is the positive logic.
    Console.WriteLine($"Action Complete!";
}
else
{
    // This is the negative logic.
    Console.WriteLine($"Error occurred: {myObject.ErrorMessage}";
}

// Don't Do This
myObject = await CallAPI(myObject);
if(myObject.ErrorMessage != "")
{
    // This is the negative logic.
    Console.WriteLine($"Error occurred: {myObject.ErrorMessage}";
}
else
{
    // This is the positivelogic.
    Console.WriteLine($"Action Complete!";
}

Keep function complexity simple – Rule of thumb is if you require excessive comments to explain what a function is doing because it’s not immediately clear or another developer has to ask multiple questions to understand it, then it should be refactored to improve clarity.

Why? – Maintains readability and understanding for future developers and code maintainability for the future.

Refactor long obscure logic within functions into smaller functions.

Why? – Improves clarity and lowers code complexity level.

Commenting

Comments should be used only to add context and explain WHY the code is structured that way when it’s not immediately clear.

Comments should not be used to explain HOW the code works, if the ‘how’ is unclear you should consider refactoring the code to improve clarity for future developers, not add numerous comments.

  • Place comment on its own line, not at end of line of code.
  • Place comment delimiter (//), then one space, then your comment.
  • Begin you comment with uppercase letter.
  • End comment with a period.
  • Free of grammar and spelling mistakes.

Why? – Helps improve readability by keeping comments clear, consistent, and concise.

// This is how a comment
// should be formatted.

Documentation commenting

All methods should have documentation comments to clearly indicate the purpose of the method and information regarding the return type and parameters. Providing documentation comments to the methods helps provide insight from within Visual Studio.

For east reference Visual Studio intelliSense has a quick helper where you can type “///” and a pre-formatted documentation comment will be generated.

Using the Notification service as an example, here is what it looks like when calling a method that had no documentation comments versus the same method now with documentation comments:

No documentation comments:

Default error notification with no documentation comments

Has documentation comments:

Default error notification with documentation comments

As you can see the documentation comments add some additional insight, especially if it’s a more complex method being called.

Information regarding Documentation Comments and additional tags can be found by following this article from Microsoft.

Rules

Always include a short summary of what the overall purpose of the method is.

Why? – Improves clarity and prevents numerous trips to the documentation.

/// <summary>
/// Used to do this action.
/// </summary>

When the method accepts parameters include the <param> tag to describe the parameter and if it’s optional indicate that

Why? – Indicates what information is expected to be passed into the method.

/// <param name="nameOfParameter">The description of this parameter.</param>

When there’s a return type describe it and use bolding for the returned object.

Why? – Improves readability and describes what’s expected to be returned.

/// <returns><strong>True</strong> if this condition, <strong>False</strong> if that condition.</returns>
Updated on February 13, 2024

Was this article helpful?

Related Articles

Need Support?
Can’t find the answer you’re looking for? Don’t worry we’re here to help!
Contact Support

Leave a Comment