Объявление переменной в операторе switch С#
Почему в выражении оператора С# для переменной, используемой в нескольких случаях, вы только объявляете ее в первом случае?
Например, следующее порождает ошибку "Локальная переменная с именем" variable "уже определена в этой области".
switch (Type)
{
case Type.A:
string variable = "x";
break;
case Type.B:
string variable = "y";
break;
}
Однако, по логике, начальная декларация не должна быть удалена, если тип Type.B
. Все переменные в выражении switch существуют в одной области видимости и создаются/распределяются до обработки любой логики?
Ответы
Ответ 1
Я полагаю, что это связано с общей областью переменной, это область уровня блока, которая определена на уровне коммутатора.
Лично, если вы устанавливаете значение для чего-то внутри коммутатора в своем примере, чтобы оно действительно имело какую-либо пользу, вы все равно захотите объявить его вне коммутатора.
Ответ 2
Если вам нужна переменная, привязанная к конкретному случаю, просто вставьте ее в свой блок:
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;
}
Ответ 3
Да, область действия - это весь блок коммутатора - к сожалению, ИМО. Однако вы можете добавлять фигурные скобки в одном случае, чтобы создать меньшую область видимости. Что касается того, созданы ли они/выделены - в стеке стека достаточно места для всех локальных переменных в методе (исключая сложности захваченных переменных). Это не так, как это пространство выделяется во время выполнения метода.
Ответ 4
Поскольку их область действия находится в блоке коммутатора. В С# Language Specification указано следующее:
Объем локальной переменной или константы, объявленной в блоке коммутатора, является блоком коммутатора.
Ответ 5
Инициализация выполняется в случае, но объявление эффективно выполняется в верхней части области.
(Псевдо-код)
switch (Type)
{
string variable;
case Type.A:
variable = "x";
break;
case Type.B:
variable = "y";
break;
}
Ответ 6
Эти переменные разделяют область действия в компиляторе С#. Тем не менее, объем не существует таким же образом в CIL. Что касается фактического создания/инициализации... модель памяти .NET позволяет движению компилятора читать/записывать бит до тех пор, пока соблюдаются простые правила, если переменная не помечена как volatile.
Ответ 7
"В моих даааах..."
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;
}