C#switch语句中的variables声明

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

例如,下面的代码会引发错误“在这个范围中已经定义了一个名为'variables'的局部variables”。

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

但是,根据逻辑,如果types是Type.B则不应该命中初始声明。 switch语句中的所有variables是否存在于单个作用域中,并且在处理任何逻辑之前是否创build/分配了这些variables?

我相信它与variables的整体范围有关,它是在交换机级定义的块级作用域。

就个人而言,如果您在示例中为开关内部的某个值设置了值,那么确实有任何好处,您仍然希望在开关外部声明它。

如果你想把一个variables作为一个特定的情况,只需要将这个case包装在它自己的块中:

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

是的,范围是整个开关块 – 不幸的是,国际海事组织。 您可以随时在一个案例中添加大括号,但是,可以创build一个较小的范围。 至于它们是否被创build/分配 – 堆栈框架为方法中的所有局部variables提供了足够的空间(不考虑捕获的variables的复杂性)。 这不是在方法执行期间分配空间。

因为他们的范围是在开关块。 C#语言规范声明如下:

在开关块中声明的局部variables或常量的范围是开关块。

在这种情况下进行初始化,但是在范围的顶部有效地完成了声明。 (伪码)

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

这些variables在C#编译器中共享作用域。 但是,范围在CIL中不存在相同的方式。 至于实际的创build/初始化…只要遵循简单的规则,.NET内存模型就可以让编译器移动读/写,除非variables被标记为volatile 。

“在我的Daaaaays …”

swicth是一个非常原始的程序实现,从C本身(甚至在C++之前)已经存在了。

整个switch是一个 ,作为一个范围包含GOTO:因此:在每种case )。 如果你拿了一些汇编程序,那可能看起来很熟悉。

这就是为什么switch使用是最有用的时候,结合使用Enum s,而不是在每一个case使用break

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