C#switch variable initialization:为什么这段代码不会导致编译器错误或运行时错误?

... case 1: string x = "SomeString"; ... break; case 2: x = "SomeOtherString"; ... break; ... 

有没有我不了解C#中的switch语句? 为什么在使用案例2时这不是错误?
编辑:此代码有效,不会引发错误。

你必须小心如何考虑这里的switch语句。 事实上, 根本没有创建可变范围 。 不要因为案例中的代码缩进而使其驻留在子范围内这一事实。

当编译一个开关块时,只需将case标签转换为标签,并根据switch表达式在switch语句的开头执行适当的goto指令。 实际上,您可以手动使用goto语句来创建“直通”情境(C#直接支持),如MSDN页面所示。

 goto case 1; 

如果您特别想在switch块中为每个案例创建范围,则可以执行以下操作。

 ... case 1: { string x = "SomeString"; ... break; } case 2: { string x = "SomeOtherString"; ... break; } ... 

要求您重新声明变量x (否则您将收到编译器错误)。 在某些情况下,确定每个(或至少一些)范围的方法非常有用,您肯定会在代码中不时地看到它。

MSDN上的文档说:

在switch语句的switch-block中声明的局部变量的范围(第8.7.2节)是switch-block。

此外,之前已经提出过类似的问题: c#switch语句中的变量声明

没有编译器错误,因为switch语句不会为变量创建新的作用域。

如果在开关内部声明变量,则变量与开关周围的代码块处于相同的范围内。 要更改此行为,您需要添加{}:

 ... case 1: // Start a new variable scope { string x = "SomeString"; ... } break; case 2: { x = "SomeOtherString"; ... } break; ... 

这会导致编译器抱怨。 但是,切换它本身并不在内部执行此操作,因此代码中没有错误。

看起来变量的范围是在开关内,而不是这种情况,可能是因为案例可以堆叠。 请注意,如果您尝试在开关外部引用x,则它将失败。

如果在case中创建任何局部变量,则不能在侧面使用它们。

 ... int opt ; switch(opt) { case 1: { string x = "SomeString"; ... } break; case 2: { string x = "SomeOtherString"; ... } break; default: { //your code } break; } ... 

将字符串声明移到之前

 switch(value) 

声明。 然后为每个案例分配x。