2013-05-22 44 views
63

为什么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; 
} 
+8

任何其他语言允许它? – Vivasaayi

+50

你为什么要这样做? – Jodrell

+12

无论是否有人会写这样的代码,这仍然是一个有趣的问题。幕后必须有一些奇怪的范围界定。 –

回答

119

因为你的缩进是误导性的,第一个代码居然是:

var s = "Nice"; 
switch (s) 
{ 
    case "HI": 
     break; 
     const string x = "Nice"; 
    case x: 
     Console.Write("Y"); 
     break; 
} 

x是在内部声明的声明(尽管在break之后),它在哪里有效。但是,直接在switch声明中它是无效的 - 唯一有效的声明是casedefault

此外,const声明是在编译时评估,所以x是,即使之前有一个break语句定义。

但是请注意,Mono的C#编译器不会编译这段代码,它抱怨说,“名字‘x’不当前范围存在”,所以单似乎实现比.NET编译更多的检查。但是,我无法在C#标准中找到任何禁止使用const声明的规则,所以我认为.NET编译器是正确的,而且Mono编译器是错误的。

+2

但是如果它确实发生中断,它怎么显示? – rtuner

+1

@rtuner我猜是因为'const'声明在编译时被移到了方法的顶部。 – CodeCaster

+21

@rtuner'const'语句不在运行时执行,它们在编译时被替换。尝试并在其上放置一个断点。 – Jodrell

7

因为语言规范不直接使一个const在你开关(仅​​情况和默认被允许):

switch (expression) 
{ 
    case constant-expression: 
     statement 
     jump-statement 
    [default: 
     statement 
     jump-statement] 
} 

其中:

expression:的积分或字符串类型的表达式。
statement:如果将控制转移到大小写或缺省值,将执行的嵌入语句。
jump-statement:将控制权移出案例主体的跳转声明。
constant-expression:根据该表达式的值将控制转移到特定的情况。

在第一种情况下,const是您的案例逻辑的一部分。常量只能在编译时重写,而不是在运行时重写。

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: 
     ... 

我betcha当,如果这是允许的,你会发现人们愿意做在那里他们所有的编程: - )

相关问题