Разработка приложений на языке C#. Полезные настройки. Особые спецификаторы формата, страница 43

·  Во-вторых, то, что лишние скобки способны повысить читабельность (даже если выражение сложное), является иллюзией,

·  В-третьих, приоритеты логических операций (!, ||, &&) так же естественны, как и приоритеты арифметических операций, известных со школьной скамьи,

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

Он просто обязан с легкостью заменять выражение:

!(!was || !isNow)   // Переменные was и isNow имеют тип bool

на:

was && isNow

а выражение: !(!was && ! isNow) на выражение: was || isNow.

Если вы не видите, что они эквивалентны, то устраните пробелы в знаниях школьного курса информатики (теоремы Де-Моргана. Когда-то нас учили запоминать их: "Крышка суммы равна произведению крышек" и "Крышка произведения равна сумме крышек").

У программиста не должно возникать желание добавить скобки в выражение:

if (GetName() && !isFinished || wasAuthorized && !isOk)

  GetData();

потому, что приоритеты выполнения операций очевидны. Вернемся к примеру, взятому из курса MS. Если в ветвях условного оператора присутствует более сложная логика, как например, во фрагменте:

if (currentPage < totalPages) // Фрагмент взят из того же источника

{

currentPage += 1;

e.HasMorePages = true;

}

else

{

e.HasMorePages = false;

}

то, все равно, следующий вариант будет более предпочтительным:

e.HasMorePages = page < totalPages; // Идентификатор page проще, чем currentPage  (не усложняйте имена локальных переменных)

if (e.HasMorePages)

page++;

Я вовсе не хочу сказать, что в Microsoft не умеют программировать. Просто там так много всего, что можно найти образцы как хорошего стиля, так и дрянного. В том же кладези мудрости (MS-курсе 2555) находим функцию (ее форматирование, соответствует оригиналу):

private void ShowPrinterInfo()

{

int  lcv;

string printerInformation = "";

int printerCount;

string currentPrinter;

bool printerIsValid;

string defaultPrinterName = "";

bool printToFile;

   // get the number of installed printers

printerCount = PrinterSettings.InstalledPrinters.Count;

for (lcv = 0;lcv <printerCount;lcv++) // Плохое форматирование. Три группы операторов цикла должны быть четко выделены

{

  if(printDocument1.PrinterSettings.IsDefaultPrinter == true) // Условие не зависит от lcv !!!.

  {

    defaultPrinterName = PrinterSettings.InstalledPrinters[lcv];

  }

}

for (lcv = 0;lcv <printerCount;lcv++)

{

  currentPrinter = PrinterSettings.InstalledPrinters[lcv];

  printDocument1.PrinterSettings.PrinterName = currentPrinter;

  printerIsValid = printDocument1.PrinterSettings.IsValid;

  printToFile = printDocument1.PrinterSettings.PrintToFile;

  printerInformation = printerInformation + currentPrinter + "\n";

  printerInformation = printerInformation + "IsValid = " + printerIsValid + "\n";

  if (currentPrinter == defaultPrinterName)

  {

    printerInformation = printerInformation+"IsDefaultPrinter = "+true.ToString()+"\n";

  }

  else

  {

    printerInformation = printerInformation+"IsDefaultPrinter = "+false.ToString()+"\n";

  }

  printerInformation = printerInformation + "PrintToFile = "+printToFile + "\n\n";

}

MessageBox.Show(printerInformation, "Installed Printers",

  MessageBoxButtons.OK, MessageBoxIcon.Information);

}

Если бы этот код создал троечник из соседней школы, то не стоило бы ломать копья, но он взят из официального курса (MOC — Microsoft Official Course). Проанализируйте код первого цикла for. Условие if внутри цикла абсолютно не зависит от перебираемых принтеров (то есть дурацкого индекса lcv) ! Результат:

·  Если текущий документ выставлен на default-принтер (а по умолчанию это так), то все принтеры будут считаться default, и последний принтер всегда "побеждает",