Объявление переменной в операторе переключения C # - PullRequest
106 голосов
/ 21 октября 2008

Почему в операторе switch C # для переменной, используемой в нескольких случаях, вы объявляете ее только в первом случае?

Например, следующее выдает ошибку «Локальная переменная с именем« переменная »уже определена в этой области».

switch (Type)
{
    case Type.A:
            string variable = "x";
                break;
    case Type.B:
            string variable = "y";
                break;
}

Однако, согласно логике, исходное объявление не должно выполняться, если тип Type.B. Все ли переменные в операторе switch существуют в одной области видимости, и созданы ли они / распределены до обработки какой-либо логики?

Ответы [ 7 ]

200 голосов
/ 21 октября 2008

Если вы хотите, чтобы переменная находилась в конкретном случае, просто заключите случай в отдельный блок:

switch (Type)
{
    case Type.A:
    {
        string variable = "x";
        /* Do other stuff with variable */
    }
    break;

    case Type.B:
    {
        string variable = "y";
        /* Do other stuff with variable */
    }
    break;
}
41 голосов
/ 21 октября 2008

Я полагаю, что это связано с общей областью действия переменной, это область уровня блока, которая определяется на уровне коммутатора.

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

31 голосов
/ 21 октября 2008

Да, область действия - весь блок переключателей - к сожалению, IMO. Однако вы всегда можете добавить фигурные скобки в одном случае, чтобы создать меньшую область видимости. Что касается того, созданы ли они / распределены - в кадре стека достаточно места для всех локальных переменных в методе (оставляя в стороне сложности захваченных переменных) Не то чтобы пространство выделялось во время выполнения метода.

10 голосов
/ 21 октября 2008

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

Область локальной переменной или константы, объявленной в блоке переключателей, - это блок переключателей.

0 голосов
/ 20 июня 2014

"По моему Daaaaays ..."

swicth - это действительно примитивная процедурная реализация, существующая с самого возраста C (даже до C++).

Целое switch представляет собой блок , который служит областью GOTO: (отсюда : в каждом case). Если вы взяли несколько классов ассемблера, это может показаться вам знакомым.

Именно поэтому использование switch наиболее полезно при сочетании с Enum с, а не с использованием break в каждом case, например

switch(mood)
{
    case Mood.BORED:
    case Mood.HAPPY:
        drink(oBeer) // will drink if bored OR happy
break;

    case Mood.SAD: // unnecessary but proofs a concept
    default:
        drink(oCoffee)
break;
}
0 голосов
/ 21 октября 2008

Переменные делят область видимости в компиляторе C #. Однако область действия не существует таким же образом в CIL . Что касается фактического создания / инициализации ... Модель памяти .NET позволяет компилятору перемещать чтение / запись немного, пока выполняются простые правила, если переменная не помечена как volatile .

0 голосов
/ 21 октября 2008

Инициализация происходит в случае, но объявление эффективно выполняется в верхней части области. (Псевдопользователей-код)

switch (Type)
{
string variable;

    case Type.A:
            variable = "x";
                break;
    case Type.B:
            variable = "y";
                break;
}
...