Перейти к основному содержимому

Создание читабельного кода с использованием условных обозначений, пробельных символов и комментариев в C#.

Введение

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

Предположим, вас попросили написать код для другой группы разработчиков. Вы встречаетесь с ними, чтобы обсудить спецификацию, и задание понятно. После встречи они говорят вам, что во время разработки вы будете работать самостоятельно. Как только вы закончите, вы передадите свой код другой группе. Задача по кодированию не выходит за рамки вашего уровня, но вам никогда не приходилось писать код, который будет поддерживать кто-то другой. Команда сказала вам, что если вы будете следовать стандартным соглашениям по кодированию на C#, то проблем не возникнет. Вы планируете изучить соглашения по кодированию C#, относящиеся к коду, над которым вы собираетесь работать.

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

К концу этого модуля вы будете писать код более целенаправленно, уделяя особое внимание читабельности и качеству кода для передачи информации как компилятору, так и другим разработчикам.

Цели обучения

В этом модуле вы научитесь:

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

Выбирайте имена переменных, соответствующие правилам и соглашениям.

Один разработчик программного обеспечения однажды сказал: «Самая сложная часть разработки программного обеспечения - это именование вещей». Имя переменной не только должно соответствовать определенным правилам синтаксиса, но и использоваться для того, чтобы сделать код более человекопонятным и удобочитаемым. Многовато для одной строки кода!

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

Существуют некоторые правила именования переменных, которые соблюдаются компилятором C#.

  • Имена переменных могут содержать алфавитно-цифровые символы и символ подчеркивания (_). Специальные символы, такие как шарп #, тире - и знак доллара $, не допускаются.
  • Имена переменных должны начинаться с буквы алфавита или символа подчеркивания, а не с цифры. Использование символа подчеркивания в начале имени переменной обычно зарезервировано для приватных полей экземпляра. - Ссылку на дальнейшее чтение можно найти в аннотации к модулю.
  • Имена переменных НЕ должны быть ключевыми словами C#. Например, не будут разрешены такие объявления имен переменных: float float; или string string;.
  • Имена переменных чувствительны к регистру, то есть string MyValue; и string myValue; - это две разные переменные.

Соглашения об именах переменных

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

  • В именах переменных следует использовать camelCase - стиль написания, при котором в начале первого слова ставится строчная буква, а в начале каждого последующего - прописная. Например: string thisIsCamelCase;.
  • Имена переменных должны быть описательными и значимыми в вашем приложении. Имя переменной должно отражать тип данных, которые она будет хранить (а не тип данных). Например: bool orderComplete;, НЕ bool isComplete;.
  • Имена переменных должны состоять из одного или нескольких целых слов, соединенных вместе. Не используйте сокращения, так как имя переменной может быть непонятно другим людям, читающим ваш код. Например: decimal orderAmount;, НЕ decimal odrAmt;.
  • Имена переменных не должны включать тип данных переменной. Вы можете встретить совет использовать такой стиль, как string strMyValue;. Это был популярный стиль много лет назад. Однако большинство разработчиков больше не следуют этому совету, и есть веские причины не использовать его.

Пример string firstName; следует всем этим правилам и соглашениям, предполагая, что я хочу использовать эту переменную для хранения данных, представляющих чье-то первое имя.

Примеры имен переменных

Вот несколько примеров объявлений переменных (с использованием общих типов данных):

char userOption;

int gameScore;

float particlesPerMillion;

bool processedCustomer;

Другие соглашения об именовании

Правила и соглашения, описанные выше, относятся к локальным переменным. Локальная переменная - это переменная, которая находится в теле метода, или переменная в консольном приложении, использующем операторы верхнего уровня (как, например, код в этом модуле).

Существуют и другие типы конструкций, которые вы можете использовать в своих приложениях, и многие из них имеют свои собственные соглашения. Например, классы часто используются в программировании на C# и имеют соответствующие соглашения. Хотя в этом модуле вы не будете создавать классы, вам важно знать, что соглашения об именовании, о которых вы только что узнали, вписываются в более широкую структуру именования.

Упражнение. Создание эффективных комментариев к коду

В этом упражнении вы добавите примечания к своему коду и временно отключите компиляцию определенных строк кода. Затем вы узнаете, как компилятор C# понимает пробелы и как использовать пробелы для повышения читаемости вашего кода.

Что такое комментарий к коду?

Комментарий к коду — это инструкция компилятору игнорировать все, что находится после символов комментария к коду в текущей строке.

// This is a code comment!

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

  • Когда вы хотите оставить заметку о замысле фрагмента кода. Когда вы пишете особенно сложный набор инструкций по кодированию, бывает полезно включить комментарии к коду, описывающие цель или ход мыслей. Ваше будущее будет вам благодарно.
  • Когда вы хотите временно удалить код из приложения, чтобы попробовать другой подход, но еще не уверены, что ваша новая идея сработает. Вы можете закомментировать код, написать новый код, и как только вы убедитесь, что новый код будет работать так, как вы хотите, вы можете смело удалить старый (закомментированный код).
  • Добавление сообщения типа TODO для напоминания о том, что вы должны посмотреть на данный фрагмент кода позже. Хотя использовать это нужно с умом, это полезный подход. Возможно, вы работаете над другой функцией, когда читаете строку кода, которая вызывает у вас беспокойство. Вместо того чтобы игнорировать новую проблему, вы можете пометить ее для изучения позже.
примечание

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

Создание и использование комментариев к коду

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

  1. На панели редактора кода Visual Studio введите следующий код:
string firstName = "Bob";
int widgetsSold = 7;
Console.WriteLine($"{firstName} sold {widgetsSold} widgets.");
  1. Чтобы изменить код с помощью комментариев и исправлений, обновите его следующим образом:
string firstName = "Bob";
int widgetsPurchased = 7;
// Testing a change to the message.
// int widgetsSold = 7;
// Console.WriteLine($"{firstName} sold {widgetsSold} widgets.");
Console.WriteLine($"{firstName} purchased {widgetsPurchased} widgets.");
  1. Уделите минуту просмотру комментариев и обновлений кода.

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

  1. Заупустите приложение. Вы должны увидеть следующий вывод:
Bob purchased 7 widgets.

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

  1. Удалите комментарии к коду. Ваш код должен соответствовать следующему:
string firstName = "Bob";
int widgetsPurchased = 7;
Console.WriteLine($"{firstName} purchased {widgetsPurchased} widgets.");
  1. Чтобы применить блочный комментарий, который закомментирует несколько строк, обновите свой код следующим образом:
/*
string firstName = "Bob";
int widgetsPurchased = 7;
Console.WriteLine($"{firstName} purchased {widgetsPurchased} widgets.");
*/

Блочные комментарии отлично подходят, если вам нужно написать длинный комментарий или удалить много строк кода. В блочных комментариях используется символ /* в начале кода и */ в конце. Использование блочного комментария - это самый быстрый и простой способ отключить три или более строк кода. 7. Замените существующий код следующим:

Random random = new Random();
string[] orderIDs = new string[5];
// Loop through each blank orderID
for (int i = 0; i < orderIDs.Length; i++)
{
// Get a random value that equates to ASCII letters A through E
int prefixValue = random.Next(65, 70);
// Convert the random value into a char, then a string
string prefix = Convert.ToChar(prefixValue).ToString();
// Create a random number, pad with zeroes
string suffix = random.Next(1, 1000).ToString("000");
// Combine the prefix and suffix together, then assign to current OrderID
orderIDs[i] = prefix + suffix;
}
// Print out each orderID
foreach (var orderID in orderIDs)
{
Console.WriteLine(orderID);
}
  1. Потратьте минутку и проверьте, сможете ли вы понять назначение кода.

Учитывая комментарии, вы, возможно, сможете понять, что делает этот код (при условии, что комментарии точно описывают текущее состояние и были обновлены по мере обновления кода). Но можете ли вы догадаться, зачем существует этот код? Было бы полезно, если бы в верхней части файла с кодом было какое-то пояснение, описывающее его назначение и контекст?

  1. Подумайте, как бы вы улучшили комментарии

Обратите внимание, что у этих комментариев есть две основные проблемы:

  • Комментарии к коду излишне объясняют очевидную функциональность отдельных строк кода. Такие комментарии считаются низкокачественными, поскольку они просто объясняют, как работает C# или методы библиотеки классов .NET. Если читатель не знаком с этими идеями, он может найти их с помощью learn.microsoft.com или IntelliSense.
  • Комментарии к коду не содержат контекста проблемы, решаемой кодом. Такие комментарии считаются низкокачественными, поскольку читатель не получает никакого представления о назначении этого кода, особенно если он связан с более крупной системой.
  1. Удалите существующие комментарии. Ваш код должен соответствовать следующему:
Random random = new Random();
string[] orderIDs = new string[5];

for (int i = 0; i < orderIDs.Length; i++)
{
int prefixValue = random.Next(65, 70);
string prefix = Convert.ToChar(prefixValue).ToString();
string suffix = random.Next(1, 1000).ToString("000");

orderIDs[i] = prefix + suffix;
}

foreach (var orderID in orderIDs)
{
Console.WriteLine(orderID);
}

Обратите внимание, что код уже менее загромождён.

  1. Чтобы добавить комментарий, объясняющий назначение вашего кода на более высоком уровне, обновите свой код следующим образом:
/*
The following code creates five random OrderIDs
to test the fraud detection process. OrderIDs
consist of a letter from A to E, and a three
digit number. Ex. A123.
*/
Random random = new Random();
string[] orderIDs = new string[5];

for (int i = 0; i < orderIDs.Length; i++)
{
int prefixValue = random.Next(65, 70);
string prefix = Convert.ToChar(prefixValue).ToString();
string suffix = random.Next(1, 1000).ToString("000");

orderIDs[i] = prefix + suffix;
}

foreach (var orderID in orderIDs)
{
Console.WriteLine(orderID);
}

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

Подведение итогов

Основные выводы из этого упражнения:

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

Упражнение - Использование пробельных символов для облегчения чтения кода

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

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

Что такое пробельные символы?

Термин «пробельные символы» относится к отдельным пробелам, создаваемым клавишей Space, табуляциям, создаваемым клавишей Tab, и новым строкам, создаваемым клавишей Enter.

Компилятор C# игнорирует пробельные символы. Чтобы понять, как игнорируются пробельные символы и как добиться максимальной ясности с помощью пробельных символов, выполните следующее упражнение.

Добавьте код, иллюстрирующий, как компилятор C# игнорирует пробелы.

  1. Введите следующий код:
// Example 1:
Console
.
WriteLine
(
"Hello Example 1!"
)
;

// Example 2:
string firstWord="Hello";string lastWord="Example 2";Console.WriteLine(firstWord+" "+lastWord+"!");
  1. Запустите код. Вы должны увидеть следующее
Hello Example 1!
Hello Example 2!
  1. Потратьте минуту на то, что этот результат говорит вам о том, как следует использовать пробельные символы в коде.

Эти два примера кода иллюстрируют две важные идеи:

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

Скорее всего, вы пишете код один раз, но читать его придется много раз. Поэтому вам следует сосредоточиться на читабельности кода, который вы пишете. Со временем вы поймете, когда и как использовать пробельные символы, такие как пробел, табуляция и новые строки.

Первые рекомендации:

  • Каждая законченная команда (оператор) должна располагаться на отдельной строке.
  • Если одна строка кода становится длинной, вы можете разбить ее на части. Однако не стоит произвольно разбивать одно утверждение на несколько строк, пока у вас нет веских причин для этого.
  • Используйте пробел слева и справа от оператора присваивания.
  1. Замените существующий код следующим кодом:
Random dice = new Random();
int roll1 = dice.Next(1, 7);
int roll2 = dice.Next(1, 7);
int roll3 = dice.Next(1, 7);
int total = roll1 + roll2 + roll3;
Console.WriteLine($"Dice roll: {roll1} + {roll2} + {roll3} = {total}");
if ((roll1 == roll2) || (roll2 == roll3) || (roll1 == roll3)) {
if ((roll1 == roll2) && (roll2 == roll3)) {
Console.WriteLine("You rolled triples! +6 bonus to total!");
total += 6;
} else {
Console.WriteLine("You rolled doubles! +2 bonus to total!");
total += 2;
}
}

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

примечание

Код использует класс Random для разработки симулятора игры в кости, где для оценки «выигрыша» используется суммарное значение трех бросков. Код начисляет дополнительные очки за выпадение двойных или тройных очков. Вам не нужно полностью понимать этот код, чтобы увидеть пользу от включения пробельных символов.

  1. Подумайте, как бы вы использовали пробельные символы, чтобы улучшить читабельность этого кода.

В этом коде есть две особенности, на которые следует обратить внимание:

  • В этом примере кода нет вертикальных пробелов. Другими словами, нет пустых строк, разделяющих строки кода. Все сливается в один плотный листинг кода.
  • Блоки кода, определяемые открывающими и закрывающими символами фигурных скобок { }, сжаты вместе, что затрудняет визуальное определение их границ.

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

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

  1. Чтобы добавить вертикальные пробелы, улучшающие читабельность, обновите код следующим образом:
Random dice = new Random();

int roll1 = dice.Next(1, 7);
int roll2 = dice.Next(1, 7);
int roll3 = dice.Next(1, 7);

int total = roll1 + roll2 + roll3;
Console.WriteLine($"Dice roll: {roll1} + {roll2} + {roll3} = {total}");

if ((roll1 == roll2) || (roll2 == roll3) || (roll1 == roll3)) {
if ((roll1 == roll2) && (roll2 == roll3)) {
Console.WriteLine("You rolled triples! +6 bonus to total!");
total += 6;
} else {
Console.WriteLine("You rolled doubles! +2 bonus to total!");
total += 2;
}
}

Первая строка пробельных символов используется для того, чтобы отделить объявление переменной dice от строк кода, используемых для присвоения значений переменным roll. Это разделение позволяет легче увидеть, как кубики используются в вашем коде.

Следующая строка пробельных символов отделяет объявление переменных бросков от объявления переменной total. Группировка объявлений трех переменных броска полезна двумя способами. Во-первых, это создает группу строк кода, включающую связанные переменные. Во-вторых, имена переменных очень похожи, и их объявление следует одному и тому же шаблону. Поэтому их объединение в группу привлекает внимание к сходству и помогает выявить различия.

Наконец, третья строка пробела отделяет другую группу связанных утверждений от вложенных утверждений if. Группа утверждений, включающая объявление total и метод Console.WriteLine(), связана скорее по цели, чем по внешнему виду. Ваш код сосредоточен на общем значении, полученном при броске трех костей, и на том, были ли в броске двойки или тройки. Эти строки связаны между собой, потому что вам нужно вычислить общее значение и сообщить пользователю о результатах броска.

Некоторые разработчики могут возразить, что между объявлением total и Console.WriteLine() следует добавить пустую строку. Опять же, выбор пробельных символов остается на ваше усмотрение. Вы должны решить, что для вас более читабельно, и последовательно использовать этот стиль.

Все, что у вас осталось, - это оператор if. Теперь вы можете рассмотреть его.

  1. Сосредоточившись на строках кода под ключевым словом if, измените свой код следующим образом:
Random dice = new Random();

int roll1 = dice.Next(1, 7);
int roll2 = dice.Next(1, 7);
int roll3 = dice.Next(1, 7);

int total = roll1 + roll2 + roll3;
Console.WriteLine($"Dice roll: {roll1} + {roll2} + {roll3} = {total}");

if ((roll1 == roll2) || (roll2 == roll3) || (roll1 == roll3))
{
if ((roll1 == roll2) && (roll2 == roll3))
{
Console.WriteLine("You rolled triples! +6 bonus to total!");
total += 6;
}
else
{
Console.WriteLine("You rolled doubles! +2 bonus to total!");
total += 2;
}
}
  1. Обратите внимание, что вы перенесли открывающие и закрывающие фигурные скобки на отдельную строку, чтобы увеличить расстояние между ними.

Символы { и } создают блоки кода. Многие конструкции C# требуют наличия блоков кода. Эти символы следует размещать на отдельной строке, чтобы их границы были хорошо видны и читаемы.

Кроме того, важно использовать клавишу табуляции, чтобы выстроить символы блоков кода под ключевым словом, к которому они относятся. Например, обратите внимание на строку кода, которая начинается с ключевого слова if. Под этой строкой находится символ фигурной скобки. Такое выравнивание позволяет легко понять, что символ { «принадлежит» оператору if. Кроме того, последний символ } также выравнивается по строке оператора if. Комбинация выравнивания и отступов позволяет легко понять, где начинается и заканчивается блок кода.

Строки кода внутри этого блока кода имеют отступ, указывающий на то, что они «принадлежат» этому блоку кода.

Аналогичная схема используется для внутренних операторов if и else, а также для кода внутри этих блоков кода.

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

Подведение итогов

Основные выводы из этого упражнения:

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

Упражнение - Выполните задание по улучшению читаемости кода

Задача на читаемость кода

В этом задании вам предстоит использовать приемы, изученные в этом модуле, для улучшения читабельности примера кода. Вам предоставляется пример кода, который плохо оформлен и прокомментирован. Ваша задача - обновить код, используя стилевые рекомендации для имен переменных, комментариев и пробельных символов, чтобы улучшить читаемость кода.

Задача кода - применение стилевых рекомендаций для улучшения читабельности

  1. Убедитесь, что в Visual Studio открыт пустой файл Program.cs.
  2. Чтобы создать исходный код для этого задания, введите следующий код:
string str = "The quick brown fox jumps over the lazy dog.";
// convert the message into a char array
char[] charMessage = str.ToCharArray();
// Reverse the chars
Array.Reverse(charMessage);
int x = 0;
// count the o's
foreach (char i in charMessage) { if (i == 'o') { x++; } }
// convert it back to a string
string new_message = new String(charMessage);
// print it out
Console.WriteLine(new_message);
Console.WriteLine($"'o' appears {x} times.");
подсказка

Целью этого кода высокого уровня является переворачивание строки и подсчет количества повторов появления определенного символа.

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

Используйте приемы, которые вы изучили в этом модуле, чтобы улучшить код и повысить его читабельность.

Заключение

Вашей целью было написать код, который легко читать и понимать.

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

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