我有两个函数,一个可以编译,另一个不能。有什么区别?
函数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++;
这不行吗?
答案 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