有什么区别,为什么Switch Case在C#中这样工作?

jus*_*god 24 .net c# switch-statement

我有两个功能,一个可以编译,另一个不能.有什么不同?

函数1是否假设案例1总是被命中,或者只是编译器问题?

public void Test(int x)
{
    switch (x)
    {
        case 1:
            uint cId = (uint)3;
            break;

        case 2:
            cId = (uint)5; //NO ERROR HERE. WHY?
            break;
    }
}

public void DeclaringInsideSwitch(int x)
{
    uint tst = 0;
    switch (x)
    {
        case 1:
            int y = 3;
            uint variable = tst;
            break;

        case 2:
            variable++; //ERROR HERE. WHY?
            break;
    }
}
Run Code Online (Sandbox Code Playgroud)

我当然尝试搜索"在C#中声明切换案例中的变量",但对我来说,它似乎只是C#中的某种错误,为了向后兼容而保留.

//在得到已经回答的警告之后,我的问题现在可以减少到它的真正含义.

为什么:

int x;
x++;
Run Code Online (Sandbox Code Playgroud)

这不行吗?

Mar*_*ell 24

基本上,变量声明实际上比你想象的要广泛; 第二个例子遭受"明确赋值",因为它被声明(更宽),但实际上没有赋值,因此++对未赋值的值没有意义.

如果你想要每个范围case,你可以做到...只需添加大括号:

        switch (x)
        {
            case 1:
            {
                uint cId = (uint)3;
                break;
            }
            case 2:
            {
                uint cId = (uint)5;
                break;
            }
        }
Run Code Online (Sandbox Code Playgroud)

有点烦恼吗?是.它反直觉吗?是.它会被改变吗?不太可能,因为这将是一个重大的突破性变化,将阻止许多现有的C#编译.

  • @KonradRudolph是的,我是的 (8认同)
  • @KonradRudolph C#语言设计/编译团队关注*大量*关于back-compat; 他们有一个非常高的栏*只是为了添加一个新警告*如果该警告可以触发现有代码(因为警告可以启用警告等) - 并且默认响应将是"通过分析器添加它" ; 我认为出售这种变化的可能性渐近接近于零. (3认同)

Dmi*_*nko 16

好吧,uint cId定义在您的情况下的{...} 范围内switch scope

switch (x)
{
    case 1:
        uint cId = (uint)3; // <- definition 
        break;

    case 2:
        // cId has been defined and thus can be assigned (initialization)
        cId = (uint)5; //NO ERROR HERE WHY?
        break;
}  // <- end of cId scope
Run Code Online (Sandbox Code Playgroud)

在第二种情况下variable定义,但作为局部变量必须在使用前初始化(增量):

switch (x)
{
    case 1:
        int y = 3;
        uint variable = tst; // <- definition 
        break;
    case 2:
        // variable defined, but has not been initialized ("case 1:" hasn't been run),
        // variable contains trash and so you can't increment it 
        variable++; //ERROR HERE WHY?
        break;
} // <- end of variable scope
Run Code Online (Sandbox Code Playgroud)