从docs(重点是我的):
Switch语句执行first switch section whose case pattern matchesa匹配表达式中的语句列表,并且其case Guard(如果存在)的计算结果为真
所以我认为这是意料之中的事.你有两条通向Console.WriteLine
的路径,其中一条或另一条匹配(而不是两条).在伪代码中,它可能看起来像这样:
string s;
object o;
if(obj is string)
{
s = (string) obj;
goto doSomething;
}
if(obj is object)
{
o = (object) obj;
goto doSomething;
}
doSomething:
// your Console.WriteLine here
// Console.WriteLine(s); Local variable 's' might not be initialized before accessing
// Console.WriteLine(o); Local variable 'o' might not be initialized before accessing
因此,如果第一个匹配,则第二个不会被处理(因为说明书说没有理由这样做),导致o
不被初始化,如果第二个匹配,则意味着第一个不匹配,因此s
不被初始化.
从specification:
一个switch
语句执行如下:
- ...
- Control is transferred according to the value of the converted switch expression:
- 同一
switch
语句中case
个标签的集合中的The lexically first pattern个标签,如果匹配Switch表达式的值,并且其防护表达式不存在或求值为真,则导致将控制转移到匹配的case
个标签之后的语句列表.
- ...
至于"为什么编译器甚至允许我在那个场景中指定变量?"--因为在我看来,规范并不禁止这样做:
每个switch_section
由一个或多个switch_labels
后跟statement_list
组成(第13.3.2节).每个包含事例的switch_label
具有相关联的模式(§11),对照该模式(§11)测试切换表达式的值.
因此,无论switch 部分中存在多少switch 标签,包括declaration one在内的所有图案都是允许的.