为什么C#允许这个:
var s = "Nice";
switch (s)
{
case "HI":
break;
const string x = "Nice";
case x:
Console.Write("Y");
break;
}
但不是这个:
var s = "Nice";
switch (s)
{
const string x = "Nice";
case x:
Console.Write("Y");
break;
}
答案 0 :(得分:119)
因为缩进是误导性的,所以第一个代码实际上是:
var s = "Nice";
switch (s)
{
case "HI":
break;
const string x = "Nice";
case x:
Console.Write("Y");
break;
}
也就是说,x
在case
语句中声明(尽管在break
之后),它是有效的。但是,直接在switch
语句中它是无效的 - 唯一有效的语句有case
和default
。
此外,const
声明在编译时进行评估,因此即使之前有x
语句,也会定义break
。
但是,请注意Mono C#编译器将无法编译此代码,它抱怨“当前范围中不存在名称'x
'”因此Mono似乎实现了比.NET编译器更多的检查。但是,我在C#标准中找不到任何禁止使用const
声明的规则,所以我假设.NET编译器是正确的,Mono编译器是错误的。
答案 1 :(得分:7)
因为语言规范不允许在您的交换机中直接使用const(仅允许大小写和默认值):
switch (expression)
{
case constant-expression:
statement
jump-statement
[default:
statement
jump-statement]
}
其中:
expression:
整数或字符串类型表达式statement:
如果控件转移到案例或默认情况下要执行的嵌入式语句。
jump-statement:
将控件移出案件正文的跳转声明constant-expression:
根据此表达式的值将控件转移到特定案例。
在第一种情况下,const是案例逻辑的一部分。 const只会起作用,因为它在编译时而不是在运行时重写。
答案 2 :(得分:1)
...因为switch
执行此操作
jump_to_the_label_matchig(s)
{
label1:
...
done_quit_this;
label2:
...
done_quit_this;
d'oh:
...
done_quit_this;
}
而不是这个
now_jump_to_the_label_matchig(s)
{
le'mme_wander_around_doing_things_that_could_have_been_done_before_me;
label1:
...
done_quit_this;
label2:
...
我认为,如果允许的话,你会发现有人愿意在那里做所有的编程: - )