2012-09-13 47 views
6

为什么下面的代码会被编译?我希望它会抱怨foo没有在第二个案例分支中声明。编译器是否处理声明,使其处于所有情况的范围内?为什么在其他情况下在一个case声明中声明的变量在范围内?

using System; 

namespace Scratch 
{ 
    class Scratch 
    { 
     public static void Main() 
     { 
      var x = 2; 
      switch (x) 
      { 
       case 1: 
        var foo = "one"; 
        Console.Out.WriteLine(foo); 
        break; 
       case 2: 
        foo = "two"; // is foo in scope here? 
        Console.Out.WriteLine(foo); 
        break; 
      } 
     } 
    } 
} 
+0

可能希望看到http://stackoverflow.com/questions/11199338/using-a-switch-statement-to-set-the-value-of-one-particular-variable-only – nawfal

回答

8

@JonSkeet说的是正确的:C/C++/C#中的“block”与逻辑意义上的“case”不同。但是他没有提到解决这个问题的“最佳实践”:如果你想在一个switch语句中声明一个变量,最好将整个逻辑“case”包装在一个块中。这样,编译器识别的逻辑“案例”和实际“范围”将是一个一样的。

public static void Main() 
{ 
    var x = 2; 
    switch (x) 
    { 
     case 1: { // notice these braces I added 
      var foo = "one"; 
      Console.Out.WriteLine(foo); 
      break; 
     } 
     case 2: 
      foo = "two"; // hooray! foo is no longer in scope here 
      Console.Out.WriteLine(foo); 
      break; 
    } 
} 
+0

你打我对同样的回应! – ColinCren

8

为什么下面的代码编译?

因为语言被设计成脑死亡的方式在这一特定领域:(

局部变量的作用域是在它的声明,它在任何时候是可访问的词汇该声明之后。

不,我不会设计这样无论是。我不是在C#开关设计的风扇的语言......

1

在C#中的变量在块级的作用域。由于该块遵循交换机状态t,foo确实在两种情况下都在范围内。

3

为了使它不能编译,你可以用大括号这样的范围:

using System; 

namespace Scratch 
{ 
    class Scratch 
    { 
     public static void Main() 
    { 
     var x = 2; 
     switch (x) 
     { 
      case 1: 
      { 
       var foo = "one"; 
       Console.Out.WriteLine(foo); 
       break; 
      } 
      case 2: 
      { 
       foo = "two"; // is foo in scope here? 
       Console.Out.WriteLine(foo); 
       break; 
      } 
     } 
    } 
} 

这迫使该变种FOO只有特定范围内的存在。

相关问题