为什么C#允许语句之后的语句,但不是之前呢?
为什么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; }
因为你的缩进是误导性的,所以第一个代码实际上是:
var s = "Nice"; switch (s) { case "HI": break; const string x = "Nice"; case x: Console.Write("Y"); break; }
也就是说, x
是在一个case
语句中声明的(尽pipe在break
),它是有效的。 但是,直接在switch
语句中它是无效的 – 唯一有效的语句是case
和default
。
此外, const
声明是在编译时计算的 ,所以即使之前有一个break
语句, x
被定义。
但是,请注意,Mono C#编译器不会编译这个代码,它抱怨说“名称x
在当前范围中不存在”,所以Mono似乎比.NET编译器执行更多的检查。 但是,我不能在C#标准中find任何禁止使用const
声明的规则,所以我认为.NET编译器是正确的,Mono编译器是错误的。
由于语言规范不允许在你的交换机中直接使用const(只允许case和default):
switch (expression) { case constant-expression: statement jump-statement [default: statement jump-statement] }
哪里:
expression:
整型或string型expression式。
statement:
如果控制转移到大小写或默认值,则embedded语句将被执行。
jump-statement:
将控制权转移出案例主体的跳转语句。
constant-expression:
根据此expression式的值,将控件转移到特定的情况。
在第一种情况下,const是你的案例逻辑的一部分。 常量只能在编译时重写,而不是在运行时重写。
…因为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: ...
我敢打赌,如果这是允许的,你会发现人们愿意在那里做所有的编程:-)