Switch案例中额外支撑的目的是什么?

Wis*_*ish 56 c# switch-statement

我对这件事很好奇......见例子:

switch(x)
{
    case(a):
        {
        //do stuff
        }
        break;
    case(b):
        //do stuff
        break;
}
Run Code Online (Sandbox Code Playgroud)

我的一生都像case b那样做了,但是因为C#允许我使用它,而Visual Studio允许我崩溃那个东西,我很好奇 - 案例a(带括号)和案例b之间的真正区别是什么?

Eri*_*ert 77

C#中包含零个或多个语句的一对括号(不是括号 - []而不是括号 - ()而是大括号 {})是一个合法的语句,因此可能出现在语句可能合法出现的任何地方.

正如其他人所指出的那样,这样做的典型原因是因为这样的说法引入了一种新的局部变量声明空间,然后定义范围内,它声明的局部变量.(回想一下,元素的"范围"是程序文本的区域,其中元素可以通过其非限定名称来引用.)

我注意到这在一个声明中特别有趣,switch因为开关中的作用域规则有点奇怪.有关它们有多奇怪的详细信息,请参阅我关于此主题的文章中的"案例3:":

http://ericlippert.com/2009/08/13/four-switch-oddities/

  • @ NateC-K:C#*确实*引入了更好的切换声明!C#设计者仔细研究了C/C++ switch语句的缺点,并在很多方面对其进行了改进.例如:(1)"不通过"规则消除了常见的错误来源.(2)您可以打开字符串.(3)您可以打开可空类型.(4)检查案例标签的类型以与开关的管理类型兼容.(5)"转到案例1"正常工作,与C++不同.等等; 在几乎所有可能的方式中,C#开关都是一种改进. (6认同)
  • @phoog:我推荐你参考C++编程语言的第3.3.1节,第2版(旧的,我知道;这是我方便的那个),它在第103页说明"请注意,案例标签不适合于在goto语句中使用." 也许C++在我没有注意的时候添加了这个功能,但是在1991年我学习C++的时候没有这个功能. (2认同)

Ian*_*Ian 71

大括号{}用于定义一组操作的范围.奇怪的是,以下将编译和工作:

private void ConnectionStateChange(object sender, StateChangeEventArgs e)
{
    string s = "hi";
    switch(s)
    {
        case "hi":
            {
                int a = 1;
                a++;
            }
            {
                int a = 2;
                a++;
            }
            break;
    }

    {
        int a = 1;
        a++;
    }
    {
        int a = 2;
        a++;
    }
}
Run Code Online (Sandbox Code Playgroud)

正如你所看到的,在那个方法中我创建了四个变量,每个变量都称为a.每个都是完全独立的,因为作为局部变量,它们只存在于自己的范围内.

这有什么意义吗?

  • 为什么奇怪?这看起来很正常(虽然做作). (55认同)
  • 如果在同一个函数中有4个不同的名为`a`的局部变量看起来很正常,那么你一直在查看错误的代码.:) (35认同)
  • 这根本不应该被认为是奇怪的. (12认同)
  • 因此设计,但引入一个新的本地范围并不是那么不寻常,imho. (11认同)
  • 接受的答案实际上无法解释(或者,实际上,明显地理解)为什么这是有用的,这是多么可悲. (2认同)

Dan*_*ite 30

它创建了一个新范围,您可以在其中创建新变量.


ABH*_*ABH 13

它为您使用的变量创建新范围.变量的范围有时可能很棘手.例如,在您发布的代码中;

switch(x)
{
    case(a):
        {
        int i = 0;
        }
        break;
    case(b):
        i = 1; // Error: The name 'i' doesn't exist in the current context
        break;
}
Run Code Online (Sandbox Code Playgroud)

这里的错误是有道理的,因为case(b)变量a是在范围之外访问的.另一方面,

switch(x)
{
    case(a):
        {
        int i = 0;
        }
        break;
    case(b):
        int i = 1; // Error: A local variable named 'i' cannot be declared in this scope because it would give a different meaning to 'i', which is already used in a 'child' scope to denote something else
        break;
}
Run Code Online (Sandbox Code Playgroud)

以上两个错误看起来相互矛盾.要解决这个问题,您应该在两个案例陈述中单独定义范围,

switch(x)
{
    case(a):
        {
        int i = 0;
        }
        break;
    case(b):
        {
        int i = 1; // No error
        }
        break;
}
Run Code Online (Sandbox Code Playgroud)

Eric Lippert与他的博客分享了一个非常好的链接,用于解释case语句中的变量范围.你应该看看它.