---
tags: guides
---
# C# Coding guidelines
authors: **Nazarii Taran**, **Roman Makhnyk**
## Naming
* General rule for naming entities - **PascalCase**.
* Start with a small letter (**camelCase**):
1. Local varaibles;
2. Formal parameters of the method.
* The names of solutions, projects, folders - **PascalCase**.
* The names of classes, structutres, constants, properties, methods - **PascalCase**.
* Use the underscore character (```_```) only in field names (except for static readonly - the rule for them is the same as for constants).
* Interface names begin with the prefix ```I```.
* Names of generic parameters begin with the prefix ```T```.
* Do not use redundant ```this```.
* Never specify access modifiers on members of interfaces.
* Always specify access modifiers to other code members.
### Examples
:broken_heart:
```csharp=
namespace Project_Name
{
}
namespace projectName
{
}
public class userService
{
}
public class User_Service
{
}
public interface Editable
{
}
public interface editable
{
}
public class BadClassMemberNamingDemo
{
public const string DEFAULT_NAME = "No Name";
private int FieldName;
private int fieldName;
public void method()
{
}
public void method_name()
{
}
public void BadArgumentsNamingDemo(int FirstArgument, int Second_Argument)
{
}
public void BadGenericNamingDemo<Entity, otherEntity>()
{
}
public void BadLocalVariableNamingDemo()
{
int local_variable = 0;
}
}
```
:green_heart:
```csharp=
namespace ProjectName
{
}
namespace Extensions
{
}
public class UserService
{
}
public interface IEditable
{
}
public interface IUserService
{
}
public class GoodMemberNamingDemo
{
public const string DefaultName = "No Name";
private int _fieldName;
public int PropertyName { get; set; }
public void MethodName()
{
}
public void GoodArgumentsNamingDemo(int firstArgument, int secondArgument)
{
}
public void GoodGenericNamingDemo<TEntity>()
{
}
public void GoodLocalVariableNamingDemo()
{
int localVariable = 0;
}
}
```
## Class layout
* The members of the class must be sorted in the following order:
1. Fields;
2. Constructors;
3. Properties;
4. Indexers;
5. Events;
6. Methods.
* Within each group, sort by static\instance:
1. Constants;
2. Static members;
3. None-static.
* Within each group is sorting by visibility:
1. public;
2. protected;
3. private.
### Examples
:broken_heart:
```csharp=
public class MyClass
{
public void Method1()
{
}
public int Property1 { get; set; }
private static int staticField = 0;
public MyClass()
{
}
private int field1;
public const string Const = "const";
protected Property2 { get; set; }
public static void Static1()
{
}
private void Method3()
{
}
private static void Static2()
{
}
public void Method2()
{
}
}
```
:green_heart:
```csharp=
public class MyClass
{
public const string Const = "const";
private static int staticField = 0;
private int field1;
public MyClass()
{
}
public string Property2 { get; set; }
protected int Property1 { get; set; }
public static void Static1()
{
}
private static void Static2()
{
}
public void Method1()
{
}
protected void Method2()
{
}
private void Method3()
{
}
}
```
## Enum
* All enum members must be numbered
* Each member must be on its own line
* Each member is named with a capital letter
### Examples
:broken_heart:
```csharp=
public enum UserStatus { active, inactive }
```
:green_heart:
```csharp=
public enum UserStatus
{
Active = 0,
Inactive = 1
}
```
## Formatting
* Tabulation - *4 spaces*. Use a space character, not a tab;
* Constructs **if-else**, **switch**, **for**, **foreach**, **do**, **do-while**, **using** must be framed in brackets ```{ }``` even if there is one line;
* Brackets must be placed one under the other;
* There must be an empty line after the structures listed above;
* There must be an empty line between class members;
* There must be a space on the sides of the binary operator (+, -, *, \, etc.);
### Examples
:broken_heart:
```csharp=
public UserModel GetUserById(long id)
{
var user = this.repository.GetById<User>(id);
if (user == null)
{
return UserModel.NullObject;
}
foreach (UserSkills skill in user.Skills)
{
// logic
}
return user.ToUserModel();
}
```
:green_heart:
```csharp=
public UserModel GetUserById(long id)
{
var user = this.repository.GetById<User>(id);
if (user == null)
{
return UserModel.NullObject;
}
foreach (UserSkills skill in user.Skills)
{
// logic
}
return user.ToUserModel();
}
```
:broken_heart:
```csharp=
public class User
{
public User() : this(-1, "No Name", -1)
{
}
public User(long id, string name, int age)
{
this.Id = id;
this.Name = name;
this.Age = age;
}
public long Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
}
```
:green_heart:
```csharp=
public class User
{
public User() : this(-1, "No Name", -1)
{
}
public User(long id, string name, int age)
{
Id = id;
Name = name;
Age = age;
}
public long Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
}
```
:broken_heart:
```csharp=
int devision=5/3;
string result = "sdf"+"sdf";
for (int i=0;i<itemCount;i++)
{
}
```
:green_heart:
```csharp=
int devision = 5 / 3;
string result = "sdf" + "sdf";
for (int i = 0; i < itemCount; i++)
{
}
```
:broken_heart:
```csharp=
public void Method() {
if (condition) {
}
}
```
:green_heart:
```csharp=
public void Method()
{
if (condition)
{
}
}
```
:broken_heart:
```csharp=
public void Method()
{
if (condition)
// one line of logic
foreach (var item in collection)
// one line of logic
}
```
:green_heart:
```csharp=
public void Method()
{
if (condition)
{
// one line of logic
}
foreach (var item in collection)
{
// one line of logic
}
}
```
## Clean code
* Each program entity (class, interface, enam, delegate) must be in its own file;
* The maximum number of method parameters is 5;
* The maximum line length is 200 characters;
* The maximum length of the method is 50 lines;
* The maximum level of nesting for constructions ```if'', ``foreach'', etc. - 2.
## Other suggestions
* Avoid dead conditional code (https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ca1508).
* Validate public method arguments (https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/CA1062).
* Use reserved type names (https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0049).
* Order of access modifiers: public, private, protected, internal, static, extern, new, virtual, abstract, sealed, override, readonly, unsafe, volatile, async.
* For simple value assignments or returns, use conditional expressions with the ternary operator (https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0046).
* If possible, use auto-properties (https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0032).
* Use collection initializers if necessary (https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0028).
* Use object initializers when needed (https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0017).
* Use **Coalesce** expressions to single-line check for ```null``` and replace with a suitable default value (https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0029-ide0030).
* Use the **null-conditional** operator to one-line test for ```null``` if you must use object members (https://docs.microsoft.com/en-us/dotnet/fundamentals/code- analysis/style-rules/ide0031).
* Use **pattern matching** to convert types (https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0020-ide0038 , https://docs.microsoft. com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0019).
* Use the **index-from-end** operator instead of ```.Length - 1''` (https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ ide0056).
* Use the **range operator** (https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0057).
* Sort the usings block alphabetically (standard sorting in VS 2019).