Книги онлайн и без регистрации » Разная литература » Интернет-журнал "Домашняя лаборатория", 2007 №9 - Журнал «Домашняя лаборатория»

Интернет-журнал "Домашняя лаборатория", 2007 №9 - Журнал «Домашняя лаборатория»

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 316 317 318 319 320 321 322 323 324 ... 415
Перейти на страницу:
[default: операторы_N оператор_пepexoда_N]

}

Ветвь default может отсутствовать. Заметьте, по синтаксису допустимо, чтобы после двоеточия следовала пустая последовательность операторов, а не последовательность, заканчивающаяся оператором перехода. Константные выражения в case должны иметь тот же тип, что и switch-выражение.

Семантика оператора switch чуть запутана. Вначале вычисляется значение switch-выражения. Затем оно поочередно в порядке следования case сравнивается на совпадение с константными выражениями. Как только достигнуто совпадение, выполняется соответствующая последовательность операторов case-ветви. Поскольку последний оператор этой последовательности является оператором перехода (чаще всего это оператор break), то обычно он завершает выполнение оператора switch. Использование операторов перехода — это плохая идея. Таким оператором может быть оператор goto, передающий управление другой case-ветви, которая, в свою очередь, может передать управление еще куда-нибудь, получая блюдо "спагетти" вместо хорошо структурированной последовательности операторов.

Семантика осложняется еще и тем, что case-ветвь может быть пустой последовательностью операторов. Тогда в случае совпадения константного выражения этой ветви со значением switch-выражения будет выполняться первая непустая последовательность очередной case-ветви. Если значение switch-выражения не совпадает ни с одним константным выражением, то выполняется последовательность операторов ветви default, если же таковой ветви нет, то оператор switch эквивалентен пустому оператору.

Полагаю, что оператор switch — это самый неудачный оператор языка C# как с точки зрения синтаксиса, так и семантики. Неудачный синтаксис порождает запутанную семантику, являющуюся источником плохого стиля программирования. Понять, почему авторов постигла неудача, можно, оправдать — нет. Дело в том, что оператор унаследован от C++, где его семантика и синтаксис еще хуже. В языке C# синтаксически каждая case-ветвь должна заканчиваться оператором перехода (забудем на минуту о пустой последовательности), иначе возникнет ошибка периода компиляции. В языке C++ это правило не является синтаксически обязательным, хотя на практике применяется та же конструкция с конечным оператором break. При его отсутствии управление "проваливается" в следующую case-ветвь. Конечно, профессионал может с успехом использовать этот трюк, но в целом ни к чему хорошему это не приводит. Борясь с этим, в C# потребовали обязательного включения оператора перехода, завершающего ветвь. Гораздо лучше было бы, если бы последним оператором мог быть только оператор break, писать его было бы не нужно и семантика стала бы прозрачной — при совпадении значений двух выражений выполняются операторы соответствующей case-ветви, при завершении которой завершается и оператор switch.

Еще одна неудача в синтаксической конструкции switch связана с существенным ограничением, накладываемым на case-выражения, которые могут быть только константным выражением. Уж если изменять оператор, то гораздо лучше было бы использовать синтаксис и семантику Visual Basic, где в case-выражениях допускается список, каждое из выражений которого может задавать диапазон значений.

Разбор случаев — это часто встречающаяся ситуация в самых разных задачах. Применяя оператор switch, помните о недостатках его синтаксиса, используйте его в правильном стиле. Заканчивайте каждую case-ветвь оператором break, но не применяйте goto.

Когда разбор случаев предполагает проверку попадания в некоторый диапазон значений, приходится прибегать к оператору if дня формирования специальной переменной. Этот прием демонстрируется в следующем примере, где идет работа надданными нашего класса Testing:

/// <summary>

/// Определяет период в зависимости от возраста — аge

/// Использование ветвящегося оператора if

/// </summary>

public void SetPeriod()

{

    if ((age > 0)&& (age <7))period=1;

    else if ((age >= 7)&& (age <17))period=2;

    else if ((age >= 17)&& (age <22))period=3;

    else if ((age >= 22)&& (age <27))period=4;

    else if ((age >= 27)&& (age <37))period=5;

    else period =6;

}

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

/// <summary>

/// Определяет статус в зависимости от периода — period

/// Использование разбора случаев — оператора Switch

/// </summary>

public void SetStatus()

{

    switch (period)

    {

        case 1:

           status = "child";

           break;

        case 2:

           status = "schoolboy";

           break;

        case 3:

           status = "student";

           break;

        case 4:

           status = "junior researcher";

           break;

         case 5:

            status = "senior researcher";

            break;

         case 6:

            status = "professor"; break;

         default:

            status = "не определен";

            break;

       }

       Console.WriteLine("Имя = {0}, Возраст = {1}, Статус = {2}", name, age, status);

}//SetStatus

Этот пример демонстрирует корректный стиль использования оператора switch. В следующем примере показана роль пустых последовательностей операторов case-ветвей для организации списка выражений одного варианта:

/// <summary>

/// Разбор случаев с использованием списков выражений

/// </summary>

/// <param name="operation">операция над аргументами</раram>

/// <param name="arg1">первый аргумент бинарной операции</param>

/// <param name="arg2">второй аргумент бинарной операции</param>

/// <param name="result">результат бинарной операции</param>

public void ExprResult(string operation,int argl, int arg2, ref int result)

{

    switch (operation)

    {

        case "+":

        case "Plus":

        case "Плюс":

            result = arg1 + arg2;

            break;

        case "-":

        case "Minus":

        case "Минус":

            result = arg1 — arg2;

            break;

        case "*":

        case "Mult":

        case "Умножить":

            result = arg1 * arg2;

            break;

        case "/":

        case "Divide":

        case "Div":

        case "разделить":

        case "Делить":

            result = arg1/arg2;

            break;

       default:

           result = 0;

          Console.WriteLine("Операция не определена");

          break;

     }

     Console.WriteLine ("{0} ({1}, {2}) = {3}",

          operation, arg1, arg2, result);

}//ExprResult

Операторы перехода

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

Оператор goto

Оператор goto имеет простой синтаксис и семантику:

goto [метка] case константное_выражение|default];

Все операторы языка C# могут иметь метку — уникальный идентификатор, предшествующий оператору отделенный от него символом двоеточия. Передача управления помеченному оператору — это классическое использование оператора goto. Два других способа использования goto (передача управления в case или default-ветвь) используются в операторе switch, о чем шла речь

1 ... 316 317 318 319 320 321 322 323 324 ... 415
Перейти на страницу:

Комментарии
Минимальная длина комментария - 20 знаков. В коментария нецензурная лексика и оскорбления ЗАПРЕЩЕНЫ! Уважайте себя и других!
Комментариев еще нет. Хотите быть первым?