141

为什么在C# switch 语句中,一个变量在多个情况下使用,你只在第一种情况下声明它?

例如,以下会引发错误“已在此范围内定义了名为 'variable' 的局部变量”。

switch (Type)
{
    case Type.A:
            string variable = "x";
                break;
    case Type.B:
            string variable = "y";
                break;
}

但是,根据逻辑,如果类型为 ,则不应命中初始声明Type.B。switch 语句中的所有变量是否都存在于单个范围内,它们是否在处理任何逻辑之前创建/分配?

4

7 回答 7

264

如果您想要一个范围为特定案例的变量,只需将案例包含在它自己的块中:

switch (Type)
{
    case Type.A:
    {
        string variable = "x";
        /* Do other stuff with variable */
    }
    break;

    case Type.B:
    {
        string variable = "y";
        /* Do other stuff with variable */
    }
    break;
}
于 2008-10-21T17:11:49.487 回答
50

我相信它与变量的整体范围有关,它是在开关级别定义的块级范围。

就个人而言,如果您在示例中为开关内的某些内容设置值以使其真正有任何好处,那么无论如何您都希望在开关之外声明它。

于 2008-10-21T16:52:11.197 回答
37

是的,范围是整个开关块 - 不幸的是,IMO。但是,您始终可以在单个案例中添加大括号以创建更小的范围。至于它们是否被创建/分配——堆栈框架有足够的空间容纳方法中的所有局部变量(撇开捕获变量的复杂性不谈)。这不像在方法执行期间分配空间。

于 2008-10-21T16:52:46.217 回答
12

因为它们的作用域在 switch 块。C# 语言规范声明如下:

在 switch 块中声明的局部变量或常量的范围是 switch 块。

于 2008-10-21T16:52:58.603 回答
0

这些变量在 C# 编译器中共享范围。但是,范围在CIL中的存在方式不同。至于实际的创建/初始化......只要遵循简单的规则,.NET 内存模型就可以让编译器稍微移动读/写,除非变量被标记为volatile

于 2008-10-21T16:55:49.643 回答
-2

switch是一个非常原始的程序实现,它从它自己的时代就已经存在C(甚至更早C++)。

整体switch是一个用作范围包含的GOTO:(因此:in each case)。如果您参加了一些汇编程序课程,那可能看起来很熟悉。

这就是为什么use 在与s 结合而不是在每个like中使用switch时最有用的原因Enumbreakcase

switch(mood)
{
    case Mood.BORED:
    case Mood.HAPPY:
        drink(oBeer) // will drink if bored OR happy
break;

    case Mood.SAD: // unnecessary but proofs a concept
    default:
        drink(oCoffee)
break;
}
于 2014-06-20T04:06:22.060 回答
-3

初始化发生在案例中,但声明实际上是在作用域的顶部完成的。(伪代码)

switch (Type)
{
string variable;

    case Type.A:
            variable = "x";
                break;
    case Type.B:
            variable = "y";
                break;
}
于 2008-10-21T16:53:01.443 回答