Соглашения о написании кода на C#
Соглашения о написании кода предназначены для реализации следующих целей.
- Создание согласованного вида кода, позволяющего читателям сосредоточиться на содержимом, а не на структуре.
- Предоставление читателям возможности делать предположения, основанные на опыте, и поэтому быстрее понимать код.
- Упрощение процессов копирования, изменения и обслуживания кода.
- Предоставление лучших методик C#.
Майкрософт использует приведенные в этой статье рекомендации для разработки примеров и документации. Они были приняты из среды выполнения .NET, руководства по стилю написания кода на C# . Их можно использовать или адаптировать в соответствии с вашими потребностями. Основные цели — это согласованность и удобочитаемость в проекте, команде, организации или исходном коде компании.
Соглашения об именах
Существует несколько соглашений об именовании, которые следует учитывать при написании кода C#.
В следующих примерах любое из рекомендаций, касающихся элементов, помеченных public , также применимо при работе с protected элементами и protected internal , которые должны быть видимы внешним вызывающим объектам.
Регистр PascalПри именовании class , record или struct Используйте регистр Pascal ("паскалкасинг").
При именовании interface Используйте регистр Pascal в дополнение к префиксу имени с I помощью. Это ясно означает, что interface это именно потребители.
При именовании public членов типов, таких как поля, свойства, события, методы и локальные функции, используйте регистр Pascal.
При записи позиционированных записей используйте для параметров регистр языка Pascal, так как это открытые свойства записи.
Дополнительные сведения о позиционированных записях см. в разделе « Позиционированный синтаксис» для определения свойства.
Неоднородный регистрПри именовании private или internal полях следует использовать регистр в стиле Camel ("камелкасинг") и добавить к _ ним префикс.
При редактировании кода C#, который соответствует соглашениям об именовании в интегрированной среде разработки, поддерживающей завершение операторов, при вводе _ отображаются все члены области объекта.
При работе с static полями, private имеющими значение s_ или internal , используйте префикс и для статического использования t_ потока.
При написании параметров метода используйте регистр в стиле Camel.
Дополнительные сведения о соглашениях об именовании C# см. в разделе стиль написания кода на c#.
Дополнительные соглашения об именованииПримеры, которые не включают директивы using, используют квалификацию пространства имен. Если известно, что пространство имен импортируется в проект по умолчанию, вам не нужно указывать полные имена из этого пространства имен. Полные имена могут быть разорваны после точки (.) Если они слишком длинны для одной строки, как показано в следующем примере.
Вам не нужно изменять имена объектов, созданных с помощью инструментов разработки Visual Studio, чтобы привести их в соответствие с другими рекомендациями.
Соглашения о макете
Чтобы выделить структуру кода и облегчить чтение кода, в хорошем макете используется форматирование. Примеры и образцы корпорации Майкрософт соответствуют следующим соглашениям.
Использование параметров редактора кода по умолчанию (логичные отступы, отступы по четыре символа, использование пробелов для табуляции). Дополнительные сведения см. в разделе "Параметры", "Текстовый редактор", C#, "Форматирование".
Запись только одного оператора в строке.
Запись только одного объявления в строке.
Если отступ для дополнительных строк не ставится автоматически, необходимо сделать для них отступ на одну позицию табуляции (четыре пробела).
Добавление по крайней мере одной пустой строки между определениями методов и свойств.
Использование скобок для ясности предложений в выражениях, как показано в следующем коде.
Соглашения о комментариях
Комментарий размещается на отдельной строке, а не в конце строки кода.
Текст комментария начинается с заглавной буквы.
Текст комментария завершается точкой.
Между разделителем комментария (/ /) и текстом комментария вставляется один пробел, как показано в следующем примере.
Не создавайте форматированные блоки из звездочек вокруг комментариев.
Убедитесь, что все открытые члены имеют необходимые комментарии XML, обеспечивая соответствующие описания их поведения.
Рекомендации по использованию языка
В следующих подразделах описаны методики, которыми руководствуется команда C# для подготовки примеров и образцов кода.
Строковый тип данныхДля сцепления коротких строк рекомендуется использовать интерполяцию строк, как показано в следующем коде.
Для добавления строк в циклах, особенно при работе с текстами больших размеров, используйте объект StringBuilder.
Неявно типизированные локальные переменныеВ случаях, когда тип переменной понятен из правой части назначения или когда точный тип не важен, рекомендуется использовать неявное типизирование для локальных переменных.
Если тип в правой части назначения не является очевидным, не рекомендуется использовать var. Не полагайтесь на то, что имя метода предоставляет информацию о типе. Тип переменной можно считать очевидным, если используется оператор new или явное приведение типа.
Не полагайтесь на имя переменной при указании ее типа. Имя может быть неверным. В следующем примере имя переменной inputInt вводит в заблуждение. На самом деле это строка.
Старайтесь не использовать var вместо var . Используйте dynamic , если требуется определение типа во время выполнения. Дополнительные сведения см. в статье Использование типа dynamic (руководство по программированию на C#).
Используйте неявную типизацию для определения типа переменной цикла в for циклах.
В следующем примере неявное типизирование используется в операторе for .
Не используйте неявную типизацию для определения типа переменной цикла в foreach циклах.
В следующем примере явное типизирование используется в операторе foreach .
Следите за тем, чтобы случайно не изменить тип элемента итерируемой коллекции. Например, можно легко переключиться с System.Linq.IQueryable на System.Collections.IEnumerable в инструкции foreach , изменяющей выполнение запроса.
Беззнаковые типы данныхКак правило, рекомендуется использовать int вместо беззнаковых типов. В C# обычно используется int . Использование int упрощает взаимодействие с другими библиотеками.
МассивыПри инициализации массивов в строке объявления рекомендуется использовать сокращенный синтаксис. В следующем примере видно, что var нельзя использовать вместо string[] .
Если экземпляр создается явно, можно использовать var .
Если вы указали размер массива, нужно поочередно инициализировать все элементы.
ДелегатыИспользуйте и Action<> вместо определения типов делегатов. В классе определите метод делегата.
Вызывайте метод с помощью сигнатуры, которую определяет делегат Func<> или Action<> .
Если вы создаете экземпляры типа делегата, используйте сокращенный синтаксис. В классе определите тип делегата и метод с соответствующей сигнатурой.
Создайте экземпляр типа делегата и вызовите его. В следующем объявлении используется сокращенный синтаксис.
В следующем объявлении используется полный синтаксис.
Операторы try - catch и using при обработке исключенийРекомендуется использовать оператор try-catch для обработки большей части исключений.
Использование оператора C# using упрощает код. Если имеется оператор try-finally , в котором единственный код в блоке является вызовом Dispose метода, используйте using оператор.
В следующем примере оператор try - finally вызывает Dispose только в блоке finally .
То же самое можно сделать с помощью оператора using .
В C# 8 и более поздних версиях используйте новый синтаксис , в котором не требуются скобки:
Операторы && и ||Чтобы избежать возникновения исключений и увеличить производительность за счет пропуска необязательных сравнений, используйте && вместо & и || вместо | при выполнении сравнений, как показано в следующем примере.
Если делитель равен нулю, второе условие в операторе if вызовет ошибку времени выполнения. &&Но оператор сокращены, если первое выражение имеет значение false. Это означает, что второе выражение не будет вычисляться. &Оператор вычисляет оба значения, что приводит к ошибке времени выполнения, когда divisor значение равно 0.
Оператор newИспользуйте одну из сокращенных форм создания экземпляров объектов, как показано в следующих объявлениях. Во втором примере используется синтаксис, который появился в версии C# 9.
Предыдущие объявления эквивалентны следующему объявлению.
Используйте инициализаторы объектов, чтобы упростить создание объектов, как показано в следующем примере.
В следующем примере задаются точно такие же свойства, как и в предыдущем, но без использования инициализаторов.
Обработка событийЕсли вы определяете обработчик событий, который не нужно удалять позже, используйте лямбда-выражение.
Лямбда-выражение сокращает приведенное ниже традиционное определение.
Статические членыДля вызова статических членов следует использовать имя класса: ClassName.StaticMember. В этом случае код становится более удобочитаемым за счет четкого доступа. Не присваивайте статическому элементу, определенному в базовом классе, имя производного класса. Во время компиляции кода его читаемость нарушается, и если добавить статический член с тем же именем в производный классе, код может быть поврежден.
Запросы LINQИспользуйте значимые имена для переменных запроса. В следующем примере используется seattleCustomers для клиентов, находящихся в Сиэтле.
Рекомендуется использовать псевдонимы для уверенности в том, что в именах свойств анонимных типов верно используются прописные буквы при помощи правил использования прописных и строчных букв языка Pascal.
Переименуйте свойства, если имена свойств в результате могут быть неоднозначными. Например, если запрос возвращает имя клиента и идентификатор распространителя, не оставляйте имена в виде Name и ID , а переименуйте их, чтобы было ясно, что Name — имя клиента и ID — идентификатор распространителя.
Рекомендуется использовать неявное типизирование в объявлении переменных запроса и переменных диапазона.
Выровняйте предложения запроса в from предложении, как показано в предыдущих примерах.
Используйте where предложения перед другими предложениями запроса, чтобы гарантировать, что последующие предложения запроса работают с сокращенным отфильтрованным набором данных.
Для доступа к внутренним коллекциям вместо join предложения используйте несколько from предложений. Например, коллекция объектов Student может содержать коллекцию результатов тестирования. При выполнении следующего запроса возвращаются результаты, превышающие 90 балов, а также фамилии учащихся, получивших такие оценки.