С# Оператор switch с/без фигурных скобок.... какая разница?

С С# всегда разрешалось пропускать фигурные скобки внутри оператора switch() между операторами case:?

Каков эффект отпущения их, как часто программисты javascript?

Пример:

switch(x)
{
  case OneWay:
  {                               //  <---- Omit this entire line
    int y = 123;
    FindYou(ref y);
    break;
  }                               //  <---- Omit this entire line
  case TheOther:
  {                               //  <---- Omit this entire line
    double y = 456.7; // legal!
    GetchaGetcha(ref y);
    break;
  }                               //  <---- Omit this entire line
}

Ответ 1

Кудрявые скобки не требуются, но они могут пригодиться, чтобы ввести новое пространство объявлений . Насколько я знаю, это поведение не изменилось с С# 1.0.

Эффект их исключения заключается в том, что все переменные, объявленные где-то внутри оператора switch, видны из их точки объявления во всех ветвях case.

См. также пример Эрика Липперта (случай 3 в сообщении):

Четыре нечеткости переключения

Пример Эрика:

switch(x)
{
  case OneWay:
    int y = 123;
    FindYou(ref y);
    break;
  case TheOther:
    double y = 456.7; // illegal!
    GetchaGetcha(ref y);
    break;
}

Это не компилируется, потому что int y и double y находятся в том же пространстве декларации, которое вводится оператором switch. Вы можете исправить ошибку, разделив пространства объявлений с помощью скобок:

switch(x)
{
  case OneWay:
  {
    int y = 123;
    FindYou(ref y);
    break;
  }
  case TheOther:
  {
    double y = 456.7; // legal!
    GetchaGetcha(ref y);
    break;
  }
}

Ответ 2

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

Они могут быть полезны для ограничения области в блоке коммутатора. Например:

int x = 5;

switch(x)
{
case 4:
    int y = 3;
    break;
case 5:
    y = 4;
    //...                      
    break;
}

против...

int x = 5;

switch(x)
{
  case 4:
  {
    int y = 3;
    break;
  }
  case 5:
  {
    y = 4;//compiling error
    //...                      
    break;
  }
}

Примечание. С# потребует от вас установить значение y в блоке case 5 в первом примере перед его использованием. Это защита от случайной переменной.

Ответ 3

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

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

Пример:

int x = 42;
{
  int y = x;
}
{
  int y = x + 1; // legal, as it in a separate scope
}

Ответ 4

Они не являются строго необходимыми, но как только вы начинаете объявлять локальные переменные (в ветвях коммутатора), они очень рекомендуются.

Это не сработает:

    // does not compile
    switch (x)
    {
        case 1 :               
            int j = 1;
            ...
            break;

        case 3:
            int j = 3;   // error
            ...
            break;
    }

Это компилируется, но он жуткий:

    switch (x)
    {
        case 1 :               
            int j = 1;
            ...
            break;

        case 3:
            j = 3;
            ...
            break;
    }

Итак, это лучше всего:

  switch (x)
    {
        case 1 : 
         {             
            int j = 1;
            ...
         }
         break;  // I prefer the break outside of the  { }

        case 3: 
         {
            int j = 3;
            ...
         }
         break;
    }

Просто держите его простым и удобочитаемым. Вы не хотите, чтобы у читателей было подробное знание правил, участвующих в среднем примере.