Skip to content

Стиль написания кода на С#

AnnaKalitka edited this page Oct 30, 2015 · 5 revisions

C#.Руководство по написанию кода.

Соглашения о написании кода предназначены для реализации следующих целей:

-Создание согласованного вида кода, позволяющего читателям сосредоточиться на содержимом, а не на структуре.

-Предоставление читателям возможности делать предположения, основанные на опыте, и поэтому быстрее понимать код.

-Упрощение процессов копирования, изменения и обслуживания кода.

-Предоставление лучших методик C#.


1. Требования

1.1 Pascal casing

Описываются имена:
• всех определений типов, в том числе пользовательских классов, перечислений, событий, делегатов и структур;
• значения перечислений;
• readonly полей и констант;
• интерфейсов;
• методов;
• пространств имен (namespace);
• свойств;
• публичных полей;
• констант;

namespace SampleNamespace
{
    enum SampleEnum
    {
        FirstValue,
        SecondValue
    }

    struct SampleStruct
    {
        public int FirstField;
        public int SecondField;
    }

    interface ISampleInterface
    {
        void SampleMethod();
    }

    public class SampleClass: SampleInterface
    {
        const int SampleConstValue = 0xffffff;
        readonly int SampleReadonlyField;

        private const int TheAnswer = 42;

        public int SampleProperty
        {
            get;
            set;
        }

        public int SamplePublicField;

        SampleClass()
        {
            SampleReadonlyField = 1;
        }

        delegate void SampleDelegate();
        event SampleDelegate SampleEvent;

        public void SampleMethod()
        {
        }
    }
}    

1.2 Camel casing

Описываются имена:
• локальных переменных;
• аргументов методов;
• защищенных (protected) полей.

protected int sampleProtectedField;
int SampleMethod(int sampleArgument)
{
 	 int sampleLocalVariable;
}

1.3 Суффиксы и префиксы

Применяются следующие суффиксы и префиксы:
• имена пользовательских классов исключений всегда заканчиваются суффиксом “Exception”;
• имена интерфейсов всегда начинаются с префикса «I»;
• имена пользовательских атрибутов всегда заканчиваются суффиксом «Attribute»;
• имена делегатов обработчиков событий всегда оканчиваются суффиксом EventHandler, имена классов-наследников от EventArgs всегда заканчиваются суффиксом EventArgs.

public class SampleException: System.Exception
{
 	 public SampleException() 
  {
  }
}

interface ISample
{
 	 void SampleMethod();
}

[System.AttributeUsage(System.AttributeTargets.All, Inherited = false, AllowMultiple = true)]
sealed class SampleAttribute: System.Attribute
{
 	 public SampleAttribute()
 	 {
  	 }
} 
public delegate void AnswerCreatedEventHandler(object sender, AnswerCreatedEventArgs e);
public class AnswerCreatedEventArgs: EventArgs
  {
   	 public int СreatedId;
    	 public int ParentId;
    	 public string CreatorName;
  }

1.4 Аббревиатуры

• при использовании аббревиатур в именах, капитализации подлежат аббревиатуры с двумя символами, в остальных аббревиатурах необходимо приводить к верхнему регистру только первый символ.

namespace Sample.IO
{
}

class HttpUtil
{
}

1.5 Закрытые поля

• имена закрытых полей всегда начинаются с префикса «_» остальная часть имени описывается с помощью Camel Casing.

private int _samplePrivateField;

1.6 Элементы управления

• употреблять с префиксом, который описывает их тип (небольшой проигрыш в длине переменной дает приличный выигрыш в наглядности и читаемости):

textBoxSample - TextBox 
lableSample - Label 
literalSample - Literal 
buttonSample - Button 
linkButtonSample - LinkButton 
imageButtonSample - ImageButton 
listSample - Все списковые элементы 
objectDataSourseSample - ObjectDataSource 
hyperLinkSample - Hyperlink 
imageSample - Image

1.7 Таким же принципом пользоваться для именования контроллеров в WinForms.


2. Рекомендации

2.1 Именование методов

• используйте конструкцию глагол-объект для именования методов

ShowUserInfo()

• в частном случае, для методов, которые возвращают значение, используйте в паре глагол-объект для глагола «Get», а для объекта – описание возвращаемого значения.

GetUserId()

2.2 Переменные, поля и свойства

• при именовании переменных избегайте использования сокращенных вариантов вроде I и t, используйте index и temp. Не используйте венгерскую нотацию или используйте ее только для закрытых членов. Не сокращайте слова, используйте number, а не num.
• рекомендуется для имен элементов управления указывать префиксы, описывающие тип элемента. Например: txtSample, lblSample, cmdSample или btnSample. Эта же рекомендация распространяется на локальные переменные сложных типов: ThisIsLongTypeName tltnSample = new ThisIsLongTypeName();
• не используйте публичные или защищенные поля, вместо этого используйте свойства;
• используйте автоматические свойства;
• всегда указывайте модификатор доступа private, даже если разрешено его опускать;
• всегда инициализируйте переменные, даже когда существует автоматическая инициализация.

2.3 Дополнительные рекомендации

• используйте пустую строку между логическими секциями в исходном файле, классе, методе;
• используйте промежуточную переменную для передачи bool-значения результата функции в условное выражение if;

bool boolVariable = GetBoolValue();
if (boolVariable)
{
}

• разрешена запись только одного оператора в строке.
• разрешена запись только одного объявления в строке.
• если отступ для дополнительных строк не ставится автоматически, необходимо сделать для них отступ на одну позицию табуляции.
• используйте скобки для ясности предложений в выражениях, как показано в следующем коде.

if ((val1 > val2) && (val1 > val3))
{
    // Take appropriate action.
}

2.4 Объем кода

• избегайте файлов с более чем 500 строками кода;
• избегайте методов с более чем 200 строками кода;
• избегайте методов с более чем 5 аргументами, используйте структуры для передачи большого числа параметров;
• одна строка кода не должна иметь длину более 120 символов.
• если аргументы метода не помещаются на одной строке, следует разбить их на несколько строк так, чтобы новвая строка начиналась на одну позицию правее открывающей скобки списка аргументов.

2.5 Комментарии

• комментарий размещается на отдельной строке, а не в конце строки кода.
• текст комментария начинается с заглавной буквы.
• комментарий пишется на английском языке. • текст комментария завершается точкой.
• между разделителем комментария и текстом комментария вставляется один пробел, как показано в следующем примере.

// The following declaration creates a query. It does not run
// the query.

• вокруг комментариев не должно быть звездочек.

2.6 Различные типы данных

• нет необходимости изменять имена объектов, созданных с помощью инструментов разработки Visual Studio, чтобы сделать их соответствующими другим соглашениям.
• приведение типов следует писать в явном виде.

double x = 1234.7;
int a;
a = (int)x;

• для сцепления коротких строк рекомендуется использовать оператор +, как показано в следующем коде.

string displayName = nameList[n].LastName + ", " + nameList[n].FirstName;

• если тип из правой части назначения не является очевидным, не рекомендуется использовать var.

int var4 = ExampleClass.ResultSoFar();

• при указании типа переменной не следует полагаться на имя переменной, оно может быть неверным.
• рекомендуется избегать использования var вместо dynamic.
• рекомендуется использовать неявное типизирование для определения типа переменной цикла в циклах for и foreach.
• как правило, рекомендуется использовать int вместо беззнаковых типов. Использование int упрощает взаимодействие с другими библиотеками.
• при инициализации массивов в строке объявления рекомендуется использовать сокращенный синтаксис.

// Preferred syntax. Note that you cannot use var here instead of string[].
string[] vowels1 = { "a", "e", "i", "o", "u" };

// If you use explicit instantiation, you can use var.
var vowels2 = new string[] { "a", "e", "i", "o", "u" };

// If you specify an array size, you must initialize the elements one at a time.
var vowels3 = new string[5];
vowels3[0] = "a";
vowels3[1] = "e";
// And so on.

• для создания экземпляров типа делегата рекомендуется использовать сокращенный синтаксис.

// In the Main method, create an instance of Del.

// Preferred: Create an instance of Del by using condensed syntax.
Del exampleDel2 = DelMethod;

// The following declaration uses the full syntax.
Del exampleDel1 = new Del(DelMethod);

• чтобы избежать возникновения исключений и увеличить производительность за счет пропуска необязательных сравнения, рекомендуется использовать && вместо & и || вместо | при выполнении сравнений, как показано в следующем примере.

Console.Write("Enter a dividend: ");
var dividend = Convert.ToInt32(Console.ReadLine());

Console.Write("Enter a divisor: ");
var divisor = Convert.ToInt32(Console.ReadLine());

// If the divisor is 0, the second clause in the following condition
// causes a run-time error. The && operator short circuits when the
// first expression is false. That is, it does not evaluate the
// second expression. The & operator evaluates both, and causes 
// a run-time error when divisor is 0.
if ((divisor != 0) && (dividend / divisor > 0))
{
    Console.WriteLine("Quotient: {0}", dividend / divisor);
}
else
{
    Console.WriteLine("Attempted division by 0 ends up here.");
}

• рекомендуется использовать инициализаторы объектов для упрощения создания объектов.
• при определении обработчика событий, который не требуется удалять позднее, рекомендуется использовать лямбда-выражение.
• переименуйте свойства, если имена свойств в результате могут быть неоднозначными. Например, если запрос возвращает имя клиента и идентификатор распространителя, не оставляйте имена в виде Name и ID, а переименуйте их, чтобы было ясно, что Name — имя клиента и ID — идентификатор распространителя.
• протоколы именовать так, чтобы их нельзя было спутать с классом. Использовать «-ing»-форму. Если протокол связан с классом, являясь его выражением, этому протоколу можно дать то же имя, что и классу.
• при создании метода первым идет модификатор доступа (public, private, internal, protected), затем уже остальные.


3. Дополнительные требования

• всегда располагайте открывающие и закрывающие фигурные скобки на новой строке.

if (a) 
{
    code ();
    code ();
}

• для коротких свойств можно писать так:

int Property 
{
    get { return value; }
    set { x = value; }
}

• для выражения if:

  • если в выражении одна строка, то пишется без скобок
  • если в if одна строка, а в else несколько (или наоборот), то обе конструкции пишутся с фигурными скобками, при этом else остается на той же строке со скобкой.
  • не используется конструкция вида if (condition) doSomesthing(),т.е. однострочная конструкция if.
    • методы в разных классах, которые делают одно и то же, стоит называть одинаково.

4. Ну и в завершение: можно почитать книжку МакКонелла "Совершенный код".


http://habrahabr.ru/post/26077/
https://msdn.microsoft.com/ru-ru/library/ff926074.aspx
http://www.mono-project.com/community/contributing/coding-guidelines/

Разработка

  1. Стили кодирования
  • [Java](Код стайл для языка Java)
  • [C/C++](Стиль написания кода на С )
  • [C#](Стиль написания кода на С# )
  • [Swift](Руководство по оформлению кода на языке Swift )
  • Написание комментариев к коммитам
  1. Android
  • Android DevGuide
  • [QR codes](Работа c QR на Android)
  • [Полезные вещи](Полезные вещи для Android разработки)
  • [Архитектура приложения](Архитектура приложения)
  • [Используемые компоненты](Используемые компоненты)
  • [Инструкция по сборке проекта](Инструкция по сборке проекта)
  1. iOS
  1. C и C++
  • [Использование CMake для проектов на C++ и C ](Использование CMake для проектов на C и CPP)

Описание

  1. Форматы файлов
  • [.bmp](Cтруктура хранения bmp файлов)
  • [.jpg](Cтруктура хранения jpg файлов)
  • [.png](Cтруктура хранения png файлов)
  1. Алгоритмы шифрования
  1. Примеры использования
  • [Библиотека матричной алгебры](Пример использования библиотеки матричной алгебры)
  1. Описание процесса кодирования файла
  2. Способ обезопасить использование приложения
  3. Java фасад библиотеки алгоритмов
  4. Алгоритм шифрования bmp на java заглушке

Тест-кейсы

  1. Матричная арифметика
  • [A+B](Сложение матриц)
  • [A*p](Умножение матрицы на скаляр)
  • [A*B](Умножение матриц)
  • [Обратные матрицы](Нахождение обратной матрицы)
  1. Взятие по модулю
  • [A mod p](Взятие матрицы по модулю простого числа)
  • [A mod P](Взятие матрицы по модулю - матрицы из простых чисел)
  1. Суперпозиция (модуль - простое число)
  • [A+B mod p](Сложение матриц по модулю простого числа)
  • [A*c mod p](Умножение матрицы на скаляр по модулю простого числа)
  • [A*B mod p](Умножение матриц по модулю простого числа)
  1. Суперпозиция (модуль - матрицы из простых чисел)
  • [A+B mod P](Сложение матриц по модулю - матрице простых чисел)
  • [A*c mod P](Умножение матрицы на скаляр по модулю - матрице простых чисел)
  • [A*B mod P](Умножение матриц по модулю - матрице простых чисел)

##Прочее

  1. [Утечки памяти](Memory Leaks)
  2. [Базовые цвета](Базовые цвета)
  3. [Clean Architecture](Clean Architecture)
Clone this wiki locally