Исходники.Ру - Программирование
Исходники
Статьи
Книги и учебники
Скрипты
Новости RSS
Магазин программиста

Главная » Статьи по программированию » .NET - Все статьи »

Обсудить на форуме Обсудить на форуме

Соглашения о кодировании
Данный документ написан на основе неофициального стандарта предложенного Mike Krueger. (The SharpDevelop C# Coding Style Guide by Mike Krueger). Благодаря данному документу у Вас есть возможность разрабатывать "читабельный" код и как следствие надежный и легко переносимый. Основным в нем является правила форматирования кода, написанного на языке C#, но большинство приемов можно применить и для других языков программирования.

Соглашения о кодировании

 

1. О руководстве "Стиль кодирования на С#" в рамках Gray LLC

Данный документ написан на основе неофициального стандарта предложенного Mike Krueger. (The SharpDevelop C# Coding Style Guide by Mike Krueger). Благодаря данному документу у Вас есть возможность разрабатывать "читабельный" код и как следствие надежный и легко переносимый. Основным в нем является правила форматирования кода, написанного на языке C#, но большинство приемов можно применить и для других языков программирования.

Документ разрабатывался для компании Gray LLC.

 

2. Организация файлов

 

2.1 Исходные файлы на C#

Старайтесь сохранять структуру классов/файлов небольшими размерами, до 2000 строк кода. Разделяйте код на файлы, это поможет Вам создавать более четкую инфраструктуру приложения. Помещайте каждый класс в отдельный файл с одноименным названием (совпадающее с названием класса) и расширением .cs.

 

2.2 Дерево файловых директорий

Создавайте директорию для каждого namespace.

Например для: MyProject.TestSuite.TestTier иерархия директорий будет иметь следующий вид: MyProject / TestSuite / TestTier.

Как видно из пример точка в строке namespace заменяется на символ слеша ("/") при написании директорий.

 

3. Структурированное расположение текста

 

3.1 Длина строки

Старайтесь избегать (насколько это возможно) строк, длинной более 80–ти символов. Присутсвие линейки в редакторе кода значительно облегчает этот контроль. Если строка превышает размер 80-ти символов используйте синтаксис переноса строки (см. 3.2)

 

3.2 Перенос длинных строк

В том случае, если строка превышает длину 80 символов, то для ее переноса используются основные принципы описанные ниже.

Строку можно переносить в случае, если:

  • Перенос после запятой.
  • Перенос после оператора.
  • Перенесенная линия по отношению к верхней должна быть сдвинута вправо как минимум на один стандартный символ табуляции либо на уровне начала переносимого выражения (см. примеры).
  • Символ Табуляции в редакторе устанавливается размером, равным 4-м стандартным символам.
Пример разбиения строки при вызове аргументов метода:
		longMethodCall(expr1, expr2, expr3,
			expr4, expr5);

Пример переноса арифметического выражения несколькими способами. Первый стандартным образом (с одинарным символом табуляции).

	var = a * b / (c - g + f) +
			4 * z; // PREFER

и вторым (с форматированием по переносимому выражению)

		var = a * b / (c - g +
	  f) + 4 * z; // AVOID

 

3.3 Пробелы

Никто, кто хочет достичь качественного уровня написания кода не должен использовать пробелы для форматирования отступов в коде. И делается это потому, что разные разработчики используют различное число для символов табуляции. Один – размер 2-х символов, другой 4-ре третий 8-мь. В случае, если вы будете использовать стандартный табулятор для отступа, то любой разработчик может перенастроить его под свой стандарт, что значительно облегчит модификацию написанного кода в будущем.

Вот несколько аргументов в пользу использования табулятора:

  • Каждый может настроить отступ под свой стандарт; Использование одного символа вместо 2-х, 4-х или 8-ми. И что самое важное легкость в выравнивании отступов: сделать это одним нажатием гораздо легче, чем несколькими; Если Вы захотите передвинуть выделенный текст на одну табуляцию вправо (клавиша Tab) или влево (Shift+Tab) то сделать это не составит труда. Большинство редакторов имеют эту возможность. Этих аргументов должно быть достаточно для того, что бы ни использовать пробелы при форматировании исходного кода.
!!! НЕ ИСПОЛЬЗУЙТЕ ПРОБЕЛЫ ВМЕСТО СИМВОЛОВ ТАБУЛЯЦИИ !!!!

 

4. Comments

 

4.1 Блочный комментарий

Как правило, используется блочный комментарий для описания, а так же стандартный «///» комментарий для самодокументирования.

Для стандартных блочных комментариев используются следующие стили:

		/*
		* Line 1
		* Line 2
		* Line 3
*/ либо такой стиль:
		/* blabla */

 

4.2 Комментарий "до конца строки"

Для комментариев в одну строку используется «С++» подобный стиль: «//» Этот стиль наиболее удобен при документировании параметров. Предпочтительно использовать данный стиль вместо /* комментарий */ там, где это возможно.

 

		int i; // переменная для цикла

 

4.3 Комментарии для самодокументирования

Теги для самодокументирования, также могут использоваться разработчиками для описания. Но должен учитываться и тот факт, что он должен согласовываться с требованиями к документированию исходного кода.

<c> <para>  <see>  
<code>  <param>  <seealso>  
<example>  <paramref>  <summary>  
<exception>  <permission>  <value>  
<include>  <remarks>    
<list> <returns>   

Данный раздел подробно описан в документации Microsoft

 

5. Объявления

 

5.1 Количество объявлений на одной линии

Общепринятым стандартом в объявлениях является одна строка на экземпляр. Благодаря этому появляется удобство чтения и написания комментария:

		int level; // indentation level
		int size; // size of table
не размещайте объявления в одну строку!
		int a, b; // Неправильно !

5.2 Инициализация

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

Например:

		string name = myObject.Name;
либо
		int val = time.Hours;

 

5.3 Объявление классов и интерфейсов

В процессе разработки классов и интерфейсов, следуйте следующим правилам:

Между названием метода и открывающей скобкой с перечислением параметров не должно присутствовать пробела.

Открывающая фигурная скобка «{« должна начинаться на следующей строке сразу под названием класса или его метода. Код, который следует под открывающей фигурной скобкой «{«, должен находится на смещении одного Tab символа вправо. Закрывающая фигурная скобка «}» должна находится на уровне открывающей и охватывать весь блок кода.

Например:

	class MySample : MyClass, IMyInterface
	{
		int myint;

		public MySample(int myint)
		{
			this.myint = myint;
		}

		void Inc()
		{
			++myint;
		}	

		void EmptyMethod()
		{
		}
	}

 

6 Операторы

 

6.1 Обычные операторы

Желательно, чтобы в каждой строке присутствовал один оператор

 

6.2 Операторы возврата

Операторы возврата не должны использовать скобок.

 

6.3 If, if-else, if else-if else операторы

Код с использованием операторов if, if-else и if else-if else должен выглядеть следующим образом:

В простом случае:

 

	if (condition) 
	{
		DoSomething();
		...
	}
В более усложненном:
	if (condition) 
	{
		DoSomething();
		...
	}
	else 
	{
		DoSomethingOther();
		...
	}
И в самом сложном:
	if (condition) 
	{
		DoSomething();
		...
	} 
	else if (condition) 
	{
		DoSomethingOther();
		...
	} 
	else 
	{
		DoSomethingOtherAgain();
		...
	}

 

6.4 For / Foreach операторы

Стиль оформления кода для оператора For должен иметь следующий вид:

	for(int i = 0; i < 5; ++i) 
	{
		...
	}
Также допускается формат в одну строку:
	for(initialization; condition; update) ;
А оператор foreach должен выглядеть следующим образом:
	foreach(int i in IntList) 
	{
		...
	}

 

6.5 While/do-while операторы

Оператор While подлежит следующему форматированию:

	while(condition) 
	{
		...
	}
Пустой оператор While может быть иметь вид:
	while(condition);
Для Do-While применим следующий формат:
	do 
	{
		...
	} while (condition);

6.6 Switch операторы

Оператор Switch должен отвечать следующему формату:

	switch (condition) 
	{
		case A:
			...
			break;
		case B:
			...
			break;
		default:
			...
			break;
	}

 

6.7 Try-catch операторы

Формат написания операторов try – catch должен иметь следующий вид:

	try 
	{
		...
	} 
	catch (Exception) 
	{}
либо
	try 
	{
		...
	} 
	catch (Exception e) 
	{
		...
	}
либо
	try 
	{
		...
	} 
	catch (Exception e) 
	{
		...
	} 
	finally 
	{
		...
	}

 

7 Пустые строки и пробелы в форматировании кода

 

7.1 Пустые строки

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

Несколькими строками могут отделяться:

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

 

7.2 Пробелы

Один пробел используеться в объявлении методов после запятой, но не перед скобками:
	TestMethod(a, b, c); 
Пример неправильного использования:
	TestMethod(a,b,c);
либо
	TestMethod( a, b, c );
Так же одиночный пробел может быть использован для выделения операторов:
	a = b;  
неправильное использование:
	a=b;
Также пробелы используються и при форматировании циклов:
	for (int i = 0; i < 10; ++i) ;
так не нужно использовать:
	for (int i=0; i<10; ++i)
либо
	for(int i=0;i<10;++i)

 

7.3 «Табличное» форматирование

При объявлении и инициализации переменных желательно использовать «табличное» форматирование:

	string name	=	"Mr. Ed";
	int myValue	= 	5;
	Test aTest	= 	Test.TestYou;

 

8 Соглашение об именовании

 

8.1 Форматы именования

 

8.1.1 Pascal Casing

При этом стиле, каждое логическое слово должно начинаться с заглавной буквы. (например: TestCounter)

 

8.1.2 Camel Casing

Это соглашение устанавливает правила написания по следующей схеме: первый символ первого логического слова с маленькой буквы, остальные логические слова с большой, подобно Pascal Casing. (Например: testCounter)

 

8.1.3 Upper case

При этом соглашении в именовании используются только заглавные буквы. Этот стиль используется только при именовании «коротких» констант, например PI или E. В остальных случаях желательно использовать Pascal Casing.

Например:

	public class Math
	{
		public const PI = ...
		public const E = ...
	}

 

8.1.4 Сводная таблица использования именований

Type Case Notes 
Class / Struct Pascal Casing   
Interface Pascal Casing Starts with I 
Enum values Pascal Casing   
Enum type Pascal Casing   
Events Pascal Casing   
Exception class Pascal Casing End with Exception 
public Fields Pascal Casing   
Methods Pascal Casing   
Namespace Pascal Casing   
Property Pascal Casing   
Protected/private Fields Camel Casing   
Parameters Camel Casing   

 

8.2 Классы и члены классов.

На текущий момент крайне не рекомендуется использовать венгерскую нотацию при помощи символа подчеркивания. В венгерской нотации использовалась суффиксная и постфиксная приставка для именования переменных.

В текущем документе Венгерская нотация рассматриваться не будет.

 

8.2.1 Именование классов

Класс должен именоваться как существительное в единственном или множественном числе;

Используется Pascal Casing (см 8.1.1);

Не используйте никаких префиксов при именовании класса.

 

8.2.2 Именование интерфейсов

При именовании интерфейс должен иметь имя существительное в единственном или множественном числе, которое максимально описывает его предназначение. (Например: IComponent or IEnumberable)

Используется Pascal Casing (см 8.1.1);

Используется в качестве префикса заглавная буква “I”, являющаяся первой буквой слова interface.

 

8.2.3 Именование перечислений

Используется Pascal Casing (см 8.1.1) как для именования enum так и для его значений; Суффиксы и префиксы не используются;

Не используйте названий в единственном числе для именования enum;

Не используйте множественного числа при именовании «полей» enum.

 

8.2.4 Константы и поля Read Only

Используется Pascal Casing (см 8.1.1);

 

8.2.5 Параметры и нестатические поля

Используйте «описательные» названия для именования полей, которые достаточно полно описывают их функциональные требования, а так их же тип. Используется Camel Casing (см 8.1.2);

 

8.2.6 Именование переменных

Используется следующий префикс для указания типов переменных:

C# Type
 .NET Framework type  Префикс  
bool  System.Boolean  b
 
byte  System.Byte  by
 
sbyte  System.SByte  sby
 
char  System.Char  c
 
decimal  System.Decimal  dc
 
double  System.Double  d
 
float  System.Single  f
 
int  System.Int32  i
 
uint  System.UInt32  ui
 
long  System.Int64  l
 
ulong  System.UInt64  ul
 
object  System.Object  o
 
short  System.Int16  sh
 
ushort  System.UInt16  ush
 
string  System.String  s
Используйте переменные i, j, k, l, m, n для оформления циклов;

Используется Camel Casing (см 8.1.2);

 

8.2.7 Именование переменных внутри методов

Для внутренних переменных методов кроме условия 8.2.6 используется префикс "_", например: _iNewRec;

Используется Camel Casing (см 8.1.2);

 

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

Называйте методы глагольными формами единственного или множественного числа; Используется Pascal Casing (см 8.1.1);

 

8.2.9 Именование свойств

Называйте свойства существительными единственного или множественного числа;

Используется Pascal Casing (см 8.1.1);

Именуйте свойства таким же имеменем как и закрытая переменная, которое использует свойство если она есть.

 

8.2.10 Именование событий

При именовании событий используйте суффикс EventHandler

Используйте два параметра именованные "sender" и "e"

Используется Pascal Casing (см 8.1.1);

Для именования классов аргументов событий используйте суффикс EventArgs

Согласуйте названия с глагольной формой

 

Советы по написанию кода

 

9.1 "Видимость"

Старайтесь применять максимум инкапсуляции для экземпляров объектов которые вы создаете. Не ставте public там где это не нужно. Используйте максимальный уровень защиты. Т.е. старайтесь открывать доступ от минимального (private) до максимального (public).

Используйте Свойства вместо прямого открытия public, для переменных класса.

 

9.2 "Магические числа"

Не используйте так называемых «магических чисел». Вместо этого объявляйте константы и статические переменные:
	public class MyMath
	{
		public const double PI = 3.14159...
	}

10 Примеры кода

 

10.1 Пример размещения фигурных скобок

	namespace ShowMeTheBracket 
	{
		public enum Test 
		{
			TestMe,
			TestYou
		}

		public class TestMeClass
		{
			Test test;

			public Test Test 
			{
				get 
				{
					return test;
				}
				set 
				{
					test = value;
				}
			}
			void DoSomething()
			{
				if(test == Test.TestMe) 
				{
					...
				} 
				else 
				{
					...
				}
			}
		}
	}

10.2 Пример именования переменных

вместо:

	for(int i = 1; i < num; ++i) 
	{
		meetsCriteria[i] = true;
	}

	for(int i = 2; i < num / 2; ++i) 
	{
		int j = i + i;
		while (j <= num) 
		{
			meetsCriteria[j] = false ;
			j += i;
		}
	}

	for(int i = 0; i < num; ++i) 
	{
		if(meetsCriteria[i]) 
		{
			Console.WriteLine(i + " meets criteria");
		}
	}
старайтесь использовать более «интеллектуальное» именование:
	for(int primeCandidate = 1; primeCandidate < num; ++primeCandidate) 
	{
		isPrime[primeCandidate] = true;
	}

	for (int factor = 2; factor < num / 2; ++factor) 
	{
		int factorableNumber = factor + factor;
		while (factorableNumber <= num) 
		{
			isPrime[factorableNumber] = false;
			factorableNumber += factor;
		}
	}

	for(int primeCandidate = 0; primeCandidate < num; ++primeCandidate) 
	{
		if(isPrime[primeCandidate]) 
		{
			Console.WriteLine(primeCandidate + " is prime.");
		}
	}
 


 


Может пригодится:


Автор: Serg Vorontsov aka V©R©N
Прочитано: 7083
Рейтинг:
Оценить: 1 2 3 4 5

Комментарии: (0)

Добавить комментарий
Ваше имя*:
Ваш email:
URL Вашего сайта:
Ваш комментарий*:
Код безопастности*:

Рассылка новостей
Рейтинги
© 2007, Программирование Исходники.Ру