有什么区别?为什么Switch Case在C#中如此工作?

时间:2018-07-23 08:57:53

标签: c# .net 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;
    }
}

我当然尝试搜索“在C#中的switch case中声明变量”,但对我来说,这似乎像现在在C#中的某种bug,为了向后兼容而保留。

// 在得到警告后,我的问题现在可以简化为真正的含义。

为什么:

int x;
x++;

这不行吗?

2 个答案:

答案 0 :(得分:24)

基本上,变量声明实际上比您想象的要宽;第二个示例遭受“确定赋值”的困扰,因为它被声明(更宽),但实际上并未赋值,因此++对未赋值毫无意义。

如果您每个case 想要作用域,就可以做到...只需添加括号:

        switch (x)
        {
            case 1:
            {
                uint cId = (uint)3;
                break;
            }
            case 2:
            {
                uint cId = (uint)5;
                break;
            }
        }

有点烦人吗?是。这是违反直觉的吗?是。会改变吗?不太可能,因为这将是一个重大的重大更改,将阻止许多现有C#的编译。

答案 1 :(得分:17)

好吧,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

在第二种情况下,定义了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