Skip to content

Latest commit

 

History

History
169 lines (131 loc) · 18.2 KB

CODESTYLE.md

File metadata and controls

169 lines (131 loc) · 18.2 KB

Требования к исходному коду на языке C#

Общие правила

Для именования используются два стиля:

Стиль Pascal

Первая буква идентификатора и первая буква каждого последующего присоединенного слова являются прописными. Стиль Pascal можно использовать для идентификаторов, состоящих из трех и более букв. Например: BackColor.

Стиль Camel ("верблюжий")

Первая буква идентификатора является строчной, а первая буква каждого последующего присоединенного слова — прописной. Например: backColor.

  • Не использовать префиксы или суффиксы (например, венгерскую нотацию), за исключением случаев, явно указанных в данном документе;
  • По возможности избегать использования сокращений;
  • Не использовать для классов, пространств имен или интерфейсов имена, потенциально или явно конфликтующие со стандартными идентификаторами, а также (по возможности) совпадающие с наименованиями классов и т.д. стандартных библиотек классов Microsoft;
  • Использовать имена, которые ясно и четко описывают предназначение и/или смысл сущности;
  • У всех элементов, поддерживающих модификатор доступа, настоятельно рекомендуется указывать модификатор. В качестве исключения допускается не указывать модификатор доступа «internal» у класса;
  • Не использовать аббревиатуры в идентификаторах, если только они не являются общепринятыми. Например, GetWindow, а не GetWin;
  • Широко распространенные акронимы рекомендуется использовать для замены длинных фраз. Например, UI вместо User Interface.

Пространства имен

  • Для именования пространств имён используется стиль Pascal;
  • Использование пространств имён является обязательным. Корневым пространством имён для всех классов, разработанных в рамках проекта OneScript, должно являться пространство OneScript, например OneScript.ScriptEngine;
  • Корневым пространством имён проекта должно являться пространство имен, одноименное самому проекту, например: OneScript.(ProjectName). При этом корневое пространство допускается опускать в физическом названии проекта, для упрощения навигации в IDE;
  • Классы, структуры, интерфейсы и перечисления должны быть сгруппированы в пространства имён, согласно их функциональности;
  • Запрещается использовать одно и то же имя для класса и для пространства имен.

Классы и структуры

  • Для именования класса необходимо использовать стиль Pascal;

  • Не рекомендуется использование вложенных типов (классов, структур, перечислений);

  • Запрещается использование общедоступных вложенных типов (классов, структур, перечислений). Для группировки типов должны использоваться пространства имен;

  • Не допускается использование специальных префиксов, поясняющих, что это класс. Например, FileStream, а не CFileStream;

  • Рекомендуется использовать составное имя, когда класс принадлежит некоторой специфичной категории, например FileStream, StringCollection, IntegrityException. Это относится к классам, которые являются потоками (Stream), коллекциями (Collection, Queue, Stack), ассоциативными контейнерами (Dictionary), исключениями (Exception);

  • Рекомендуется каждый класс и структуру объявлять в отдельном файле исходного кода с названием, совпадающем с названием класса/структуры;

  • Рекомендуется члены класса отделять друг от друга одной пустой строкой;

  • Члены класса должны быть упорядочены в следующем порядке:

    • вложенные типы;
    • поля;
    • конструкторы;
    • свойства;
    • методы;

    При этом частные (private) методы надо стараться располагать после методов, его вызывающих, как можно "ближе" к ним.

Константы

  • Имена констант записываются заглавными буквами, отдельные слова разделяются подчеркиванием, например MAX_COUNT, REQUEST_IN_ACTION;
  • В тексте программы не должны использоваться «магические числа», необходимо использовать константы;
  • Допустимо использование констант, таких как 0, 1, -1 в том случае, когда они несут самостоятельную смысловую нагрузку (инкремент/декремент счётчика, инверсия знака, проверка длины строки на неравенство 0). Также допустимы явные случаи использования констант при их осмысленности (например, использование числа 100 при вычислении процентных показателей).

Поля

  • Все поля должны быть закрытыми (private). Для доступа к полю использовать свойства с необходимым уровнем видимости. При возможности использовать свойства с указанным модификатором доступа к аксессору, например:
public String Name { get; private set; }
  • Для именования полей используется стиль Camel с префиксом «_»;

Свойства

  • Для именования свойств используется стиль Pascal;
  • Свойства для чтения не должны изменять внешнее состояние объекта;
  • В именах логических свойств используйте утвердительную фразу (CanSeek вместо CantSeek). К именам логических свойств можно дополнительно прибавлять префикс Is, Can или Has, но только тогда, когда он действительно необходим;
  • Не рекомендуется использовать свойства, доступные только для записи. Вместо этого следует использовать метод для установки значения свойства. Имя метода должно начинаться с Set, за которым следует требуемое имя свойства;
  • Блок свойства, содержащий методы get- set- должен находиться на отдельной строке. Методы get- set- также должны находиться на отдельной строке. Если тело метода состоит из одного оператора\выражения, допускается размещать его в одной строке, без переноса. Например:

Неправильно:

public Boolean IsEmpty { get { return body == null; } }
public Boolean IsEmpty 
{ get { return body == null; } }

Правильно

public Boolean IsEmpty 
{ 
    get { return body == null; } 
}

Методы

  • Для именования методов используется стиль Pascal;
  • Длина тела метода по возможности не должна превышать 100 строк. В противном случае это признак плохого дизайна [2].

Параметры методов

  • Для регистра букв в имени параметра используется стиль Camel;
  • Не рекомендуется передавать в метод более 5 параметров. В случае возникновения подобной ситуации рекомендуется воспользоваться рефакторингами "Замена параметра вызовом метода", "Сохранение всего объекта", "Введение граничного объекта" [2];
  • Из имени и типа параметра должны быть понятны его назначение и смысл.

Локальные переменные

  • Для регистра букв в именах переменных используется стиль Camel;
  • Рекомендуется объявлять переменные непосредственно перед их использованием;
  • Счетчики в циклах традиционно называют i, j если нет более семантически подходящего имени, например columnIndex;
  • Для временных локальных переменных, используемых в коротких участках кода, можно давать имена, состоящие из начальных букв слов имени типа;
  • Не допускается объявлять более одной переменной в одной инструкции;
  • Рекомендуется использовать ключевое слово var вместо явного указания типа переменной.

Интерфейсы

  • Для именования интерфейса необходимо использовать стиль Pascal;
  • Для идентификатора интерфейса необходимо использовать описывающее существительное, прилагательное или одно или несколько прилагательных и существительное. Например, IComponent – это описывающее существительное, ICustomAttributeProvider – это конкретизированное прилагательными существительное, а IPersistable – это характеризующее прилагательное;
  • Для интерфейсов используется префикс I (заглавная i), чтобы уточнить, что тип является интерфейсом. По возможности надо избегать идентификаторов интерфейсов с двумя I в начале;
  • Каждый интерфейс должен быть объявлен в отдельном файле, с именем, совпадающем с наименованием интерфейса.

Правила оформления кода

  • Для отступов в начале строки рекомендуется использовать табуляцию, а не пробелы;
  • Рекомендуется избегать строк длиной более 120 символов и перенести инструкцию на другую строку;
  • При переносе части кода инструкций и описаний на другую строку вторая и последующая строки должны быть отбиты вправо на один отступ (табуляцию);
  • При переносе запятая или знак операции оставляется на предыдущей строке;
  • Запрещается размещать несколько инструкций на одной строке. Каждая инструкция должна начинаться с новой строки;
  • Для разделения двух логических секций в исходном коде использовать одну пустую строку;
  • После строки с закрывающей фигурной скобкой должна быть вставлена пустая строка, кроме случая когда это закрывающая скобка блока, последнего в блоке более высокого уровня (например, скобка метода, последнего в классе);
  • Количество уровней вложенности, например условных операторов должен быть минимальным. Если не удается уменьшить уровень вложенности, возможно имеет смысл вынести вложенный блок в самостоятельный метод. В идеале блоки в командах if, else, while и т.п. должны состоять из одной строки, в которой обычно содержится вызов метода [1];
  • Если вложенный блок состоит из одного оператора (выражения), допускается не обрамлять его фигурными скобками, но необходимо поместить его на отдельную строку, с отступом, например:

Недопустимо:

if (!canRead) return;
if (!canRead) { return; }

Допустимо:

if (!canRead) 
    return;
if (!canRead) 
{
    return;
}
  • После блока следует вставить пустую строку;
  • Классы и интерфейсы следует объявлять в отдельных файлах;
  • Методы разделяются одной пустой строкой;
  • После запятой должен быть пробел. После точки с запятой, если она не последняя в строке (напр. в инструкции for), должен быть пробел. Перед запятой или точкой с запятой пробелы не ставятся;
  • Все не унарные операторы должны быть отделены пробелом от операндов с обеих сторон;
  • Файлы должны содержать только используемый код, неиспользуемые методы, классы, должны быть удалены из проекта;
  • Области #region…#endregion должны использоваться только в обоснованных случаях, например, для ограничения реализации отдельных интерфейсов внутри класса. Длинные методы, классы и прочие элементы кода, требующие свертки кода только из-за своего размера – признак некачественного дизайна; в этих случаях рекомендуется рассмотреть возможность таких рефакторингов, как "Выделение метода", "Выделение класса", "Выделение подкласса" и пр. (см. [2]).

Комментарии

  • Для описания классов и открытых методов используются XML documentation-комментарии;
  • Рекомендуется отделять текст комментария одним пробелом «// Текст комментария»;
  • Не следует запутанный код загромождать большим количеством комментариев, рекомендуется потратить время на исправление кода, сделав его более ясным для понимания;
  • При возвращении изменений на сервер из исходного кода должны быть убраны закомментированные блоки кода. Для хранения истории изменений служит Git.

Источники

  1. "Чистый код", Р. Мартин
  2. "Рефакторинг. Улучшение существующего кода", М. Фаулер
  3. "Инфраструктура программных проектов", К. Цвалина, Б. Адамс