Вопрос по c#, switch-statement – Какова цель использования дополнительных скоб в корпусе коммутатора?

56

Мне это интересно ... см. Пример:

<code>switch(x)
{
    case(a):
        {
        //do stuff
        }
        break;
    case(b):
        //do stuff
        break;
}
</code>

Я всю свою жизнь делал это, как случай b, но поскольку C # позволяет мне использовать его, а Visual Studio позволяет мне свернуть эту вещь, мне любопытно - какова реальная разница между случаем a (с фигурными скобками) и случаем b ?

Не важно. Просто иногда вы хотите создавать и использовать объекты, относящиеся к конкретному случаю. Без скобок все, что вы определяете, имеет более широкую область видимости. Robinson
Смотрите такжеstackoverflow.com/q/3652408/292060 goodeye
Не то, что вы спросили, но я нахожу долгоcase блоки трудно читать. Если мне нужно определить объем или любую другую сложность, он получит новый метод. Jay Bazuzi
Разницы нет, за исключением того, что переменные, определенные в случае a, видны только в этом блоке. juergen d

Ваш Ответ

4   ответа
30

в которой вы можете создавать новые переменные.

77

Пара брекетов (неbrackets -- [] -- и неparentheses -- () -- ноbraces {}) с нулем или более утверждений в них является юридическим утверждением в C #, и, следовательно, может появляться везде, где заявление может появляться на законных основаниях.

Как уже отмечали другие, типичная причина для этого заключается в том, что такое утверждение вводит новыйlocal variable declaration space, который затем определяетscope из локальных переменных, объявленных в нем. (Напомним, что «область действия» элементаthe region of program text in which the element may be referred to by its unqualified name.)

Я отмечаю, что этоparticularly интересно вswitch заявление, потому что правила видимости в переключателе немного странные. Подробнее о том, как они странны, см. В разделе «Случай 3:» в моей статье на эту тему:

http://ericlippert.com/2009/08/13/four-switch-oddities/

Я всегда чувствовал разочарование в связи с тем, что в C # не было введено более умного оператора switch, поскольку переключатель C является одной из наиболее причудливых и проблемных конструкций в программировании.
+1 за истинный источник.
@phoog: я отсылаю вас к разделу 3.3.1 языка программирования C ++, 2-е издание (я знаю, что это старое; это тот, который мне удобен), в котором говорится на странице 103 "Обратите внимание, что метка кейса не является подходящая метка для использования в операторе goto. & quot; Возможно, C ++ добавил эту функцию, хотя я не обращал на это внимания, но у нее не было этой функции в 1991 году, когда я изучал C ++.
You can switch on strings является одной из наиболее недооцененных функций. Так много языков не допускают этого (например, Java или Delphi), и это превращает простую проблему в большой каскад if..elseif.
@ NateC-K: C #did представить лучшее заявление о переключении! Разработчики C # внимательно изучили недостатки оператора переключателя C / C ++ и улучшили его во многих отношениях. Например: (1) «Не провалиться» Правило устраняет общий источник ошибок. (2) Вы можете включить строки. (3) Вы можете включить обнуляемые типы. (4) Типы ярлыков корпуса проверяются на совместимость с типом управления выключателя. (5) «Перейти к случаю 1» работает правильно, в отличие от C ++. И так далее; почти во всех мыслимых отношениях C # switch - это улучшение.
71

Скобки {} используются для определения области действия для набора операций. Как ни странно, будет скомпилировано и работать следующее:

private void ConnectionStateChange(object sender, StateChangeEventArgs e)
{
    string s = "hi";
    switch(s)
    {
        case "hi":
            {
                int a = 1;
                a++;
            }
            {
                int a = 2;
                a++;
            }
            break;
    }

    {
        int a = 1;
        a++;
    }
    {
        int a = 2;
        a++;
    }
}

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

Это имеет какой-то смысл?

Почему странно? Это выглядит довольно нормально (хотя и надуманным).
Это не должно считаться странным вообще.
Следовательно, придумано, но введение нового локального контекста не так уж необычно, imho.
Если есть 4 разных локальных переменныхa та же самая функция выглядит нормально для вас, вы все это время просматривали неправильный код. :)
Как печально, что принятый ответ на самом деле не объясняет (или, конечно, не понимает), почему это полезно.
13

которые вы использовали. Объем переменных иногда может быть хитрым. Например, в коде вы разместили;

switch(x)
{
    case(a):
        {
        int i = 0;
        }
        break;
    case(b):
        i = 1; // Error: The name 'i' doesn't exist in the current context
        break;
}

Ошибка имеет смысл здесь, как вcase(b) переменнаяa доступ вне области. Теперь с другой стороны,

switch(x)
{
    case(a):
        {
        int i = 0;
        }
        break;
    case(b):
        int i = 1; // Error: A local variable named 'i' cannot be declared in this scope because it would give a different meaning to 'i', which is already used in a 'child' scope to denote something else
        break;
}

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

switch(x)
{
    case(a):
        {
        int i = 0;
        }
        break;
    case(b):
        {
        int i = 1; // No error
        }
        break;
}

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

Похожие вопросы