Для именования используются два стиля:
Первая буква идентификатора и первая буква каждого последующего присоединенного слова являются прописными. Стиль Pascal можно использовать для идентификаторов, состоящих из трех и более букв. Например: BackColor
.
Первая буква идентификатора является строчной, а первая буква каждого последующего присоединенного слова — прописной. Например: 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.
- "Чистый код", Р. Мартин
- "Рефакторинг. Улучшение существующего кода", М. Фаулер
- "Инфраструктура программных проектов", К. Цвалина, Б. Адамс