C # switch 语句中的变量声明

为什么在 C # switch 语句中,对于多种情况下使用的变量,只在第一种情况下声明它?

例如,下面抛出错误“在这个作用域中已经定义了一个名为‘ variable’的局部变量”。

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

但是,根据逻辑,如果类型为 Type.B,则不应该执行初始声明。Switch 语句中的所有变量是否存在于单个作用域中,它们是否在处理任何逻辑之前被创建/分配?

68229 次浏览

我相信它与变量的整体作用域有关,它是在开关级别定义的块级作用域。

就个人而言,如果您在示例中为开关内部的某个东西设置一个值,以便它真正有任何好处,那么无论如何您都应该在开关之外声明它。

是的,范围是整个交换机块-不幸的是,国际海事组织。但是,您总是可以在一个大小写中添加大括号,以创建一个更小的作用域。至于是否创建/分配了这些变量——堆栈框架对于方法中的所有局部变量都有足够的空间(不考虑捕获变量的复杂性)。这不像是在方法执行期间分配的空间。

因为它们的作用域在开关块上:

在开关块中声明的局部变量或常量的作用域是开关块。

初始化是在这种情况下进行的,但声明实际上是在作用域的顶部完成的。 (伪代码)

switch (Type)
{
string variable;


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

这些变量在 C # 编译器中共享作用域。但是,作用域在 CIL中的存在方式不同。至于实际的创建/初始化..。NET 内存模型允许编译器移动读/写一点,只要遵循简单的规则,除非变量被标记为 反复无常

如果希望变量的作用域限定在特定的情况下,只需将情况包含在它自己的块中:

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;
}

switch是一个真正原始的过程实现,自 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;
}