---
tags: guides
---
# C# Coding guidelines
:warning: OBSOLETE
New page - https://hackmd.io/@w9ExEETAR0Ko_y7OGGa1IQ/r1eYwav1t
## Naming
* Общее правило для именования сущностей - **UpperCamelCase**.
* С маленькой буквы начинаются:
1. Поля;
2. Локальные переменные;
3. Формальные параметры метода.
* Имена солюшенов, проджей, папок - **UpperCamelCase**.
*
* Не использовать символ нижнего подчеркивания (```_```) в именах.
* Ко всем none-static членам внутри класса обращаться через ключевое слово ```this```.
* Имена интерфейсов начинаются с префикса ```I```.
* Имена generic-параметров начинаются с префикса ```T```.
### Примеры
: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
* Члены класса должны быть отсортированы в следующем порядке:
1. Поля;
2. Конструкторы;
3. Свойства;
4. Индексаторы;
5. События;
6. Методы.
Внутрий каждой группы сортировка по static\instance:
1. Константы;
2. Static члены;
3. None-static.
Внутрий каждой группы сортировка по области видимости:
1. public;
2. protected;
3. private.
### Примеры
: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()
{
}
public void Method2()
{
}
private void Method3()
{
}
}
```
## Enum
* Все мемберы энамки должны быть пронумерованны
* Каждый мембер должен быть на своей строке
* Каждый мембер именуется с большой буквы
### Примеры
:broken_heart:
```csharp=
public enum UserStatus { active, inactive }
```
:green_heart:
```csharp=
public enum UserStatus
{
Active = 0,
Inactive = 1
}
```
## Formatting
* Табуляция - *4 пробела*. Использовать символ пробела, а не таб;
* Конструкции **if-else**, **switch**, **for**, **foreach**, **do**, **do-while**, **using** должны быть обрамлены в скобочки ```{ } ``` даже если там одна строчка;
* Скобочки должны быть расположены одна под другой;
* После вышеперечисленных конструкций должна быть пустая строка;
* Между членами класса должна быть пустая строка;
* По бокам бинарного оператора (+, -, *, \ и т.д.) должен быть пробел;
### Примеры
: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)
{
this.Id = id;
this.Name = name;
this.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
* Каждая программная сущность (класс, интерфейс, энам, делегат) должна быть в своём файле;
* Максимальное кол-во параметров метода - 5;
* Максимальная длинна строки - 200 символов;
* Максимальная длинна метода - 50 строк;
* Максимальный уровень вложенности для конструкций ```if```, ```foreach``` и т.д. - 2.