-2

可能重复:
c# switch 语句中的变量声明
Switch case 中额外大括号的目的是什么?

今天我正在编写一小段代码,在调试时,VS 打了我一巴掌,告诉我我的局部变量名称犯了一个大错误:“一个名为‘i’的局部变量已经在这个范围内定义了”。

MyEnum enumerator = MyEnum.B;

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

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

所以我说“好吧 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

3 回答 3

6

当您{}在不同的case块中添加 时,您正在引入范围

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

在您使用的最后两个示例中s- 第一个很好,正如在fors中声明的那样,可以使用 in ,但是使用大括号, in 的声明在其自己的范围内,在外部不可见 - 所以in是未知,需要重新声明。caseMyEnum.AMyEnum.BMyEnum.AMyEnum.Bs

于 2013-01-18T11:21:45.123 回答
5

首先,翻译成 IL 有点无关紧要。IL 根本没有相同的范围概念。这都是关于 C# 语言规范的。

非常简单,真的:局部变量的作用域是声明它的,当另一个同名的局部变量在作用域内时,你不能声明一个局部变量。

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

  • 在您的第二段代码中,每个i变量的范围只是由花括号创建的块 - 它们位于完全独立的范围内,没有嵌套,所以没关系。

  • 在您的第三段代码中,变量s在第二种情况的范围内,因为它的范围是整个 switch 语句 - 所以可以使用它。

  • 在您的第四段代码中,该变量s声明它的块的范围内(在案例 A 内),因此它不在案例 B 的范围内。

强烈建议不要使用像你的第三段代码这样的代码。会让很多人感到困惑。如果您真的想要一个适用于多种情况的变量,我会在 switch 语句之前声明它。

于 2013-01-18T11:23:02.823 回答
-1

将支架置于break内侧会使其断裂到支架的末端,此时您case会跌倒。您需要break大括号之外的语句。例如

case MyEnum.A:
{
    String s = "hello";
    Console.WriteLine(s);
}
break;
于 2013-01-18T11:22:30.437 回答