2013-01-18 162 views
-2

Possible Duplicate:
Variable declaration in c# switch statement
What is the purpose of the extra braces in Switch case?switch语句

今天,我写了一小块代码,并在调试时间的奇怪的行为,VS打了我,并告诉我,我犯了大错我的本地变量名:“一个局部变量命名'我'已经在此范围内定义“。所以我说:“好的VS,让我立刻修复它,我想首先考虑我的案例,因为我更喜欢它们!”。所以我做了我的化妆品改变......但突然停止VS呜呜有关错误:

MyEnum enumerator = MyEnum.B; 

switch (enumerator) 
{ 
    case MyEnum.A: 
    { 
     Int32 i = 0; 
     // DoStuffsA(); 
     break; 
    } 

    case MyEnum.B: 
    { 
     Double i = 0D; 
     // DoStuffsB(); 
     break; 
    } 
} 

好吧......我知道的“范围”的意思,我知道我产生了两个不同的范围,像这样。问题是我不知道switch语句是如何被转换成IL代码的,我总是认为所有的case语句都被放入switch范围,不管大括号是否被使用。所以...下面的古怪可以编译,对吧?

MyEnum enumerator = MyEnum.B; 

switch (enumerator) 
{ 
    case MyEnum.A: 
     String s = "Hello!"; 
     Console.WriteLine(s); 
     break; 

    case MyEnum.B: 
     s = "Goodbye!"; 
     Console.WriteLine(s); 
     break; 
} 

但不是以下之一:

MyEnum enumerator = MyEnum.B; 

switch (enumerator) 
{ 
    case MyEnum.A: 
    { 
     String s = "hello"; 
     Console.WriteLine(s); 
     break; 
    } 

    case MyEnum.B: 
    { 
     s = "goodbye"; 
     Console.WriteLine(s); 
     break; 
    } 
} 

一些能更好地解释我的编译器的行为在这种情况呢? 非常感谢!

回答

4

首先,与IL的翻译有点不相关。 IL根本不具有相同的范围概念。这完全是关于C#语言规范的。

这真的很简单,真的:局部变量的范围是其中声明了它,并且当同一名称的另一个局部变量在范围内时,您不能声明一个局部变量。

  • 在您的第一段代码中,范围i是整个switch语句。你的第二个声明试图在同一范围内声明另一个i变量,因此失败。

  • 在你的第二段代码中,每个i变量的作用域就是由花括号创建的块 - 它们在完全独立的作用域中,没有嵌套,所以没问题。

  • 在您的第三段代码中,变量s在第二种情况下的作用域,因为它的作用域是整个switch语句 - 所以使用它是很好的。

  • 在你的代码第四片断中,所述可变s在其中它被声明(情况A内)的块的范围,所以它不是在范围的情况下,B.

我会强烈建议不要使用代码,如你的第三段代码尽管。它会混淆许多人。如果你真的想要一个在多个case范围内的变量,我会在之前声明switch语句。

5

当您在不同的case块中添加{}时,您正在引入示波器

没有它们,所有case块都在一个范围内。

有了您的两个例子,在您使用s - 第一个是好的,因为scaseMyEnum.A所以在MyEnum.B使用声明,但与大括号,在MyEnum.A声明是在它自己的范围,在外面不可见 - 所以在MyEnum.Bs未知,需要重新申报。

0

使大括号内的break导致它打破到大括号的末端,此时您的case落空。你需要大括号外的break声明。例如。

case MyEnum.A: 
{ 
    String s = "hello"; 
    Console.WriteLine(s); 
} 
break;