Tim*_*man 35 c# compiler-construction exception
如果我这样做,我得到一个System.StackOverflowException:
private string abc = "";
public string Abc
{
get
{
return Abc; // Note the mistaken capitalization
}
}
Run Code Online (Sandbox Code Playgroud)
我理解为什么 - 属性引用自身,导致无限循环.(在此处和此处查看以前的问题).
我想知道的(以及我之前没有看到的问题)是为什么C#编译器没有抓住这个错误?它检查一些其他类型的循环引用(继承自己的类等),对吗?只是这个错误不常见,值得检查吗?或者是否有一些我没有想到的情况,当你想要一个房产以这种方式实际引用自己的时候?
Bra*_*don 44
您可以在此处的最后一条评论中看到"官方"原因.
微软于2008年11月14日19:52发布
感谢您对Visual Studio的建议!
你是对的,我们可以很容易地检测属性递归,但我们不能保证递归没有任何有用的东西.属性的主体可以设置对象上的其他字段,这些字段会更改下一个递归的行为,可以根据来自控制台的用户输入更改其行为,或者甚至可以根据随机值进行不同的操作.在这些情况下,自递归属性确实可以终止递归,但我们无法确定在编译时是否就是这种情况(没有解决暂停问题!).
由于上述原因(以及不允许这样做的重大变化),我们无法禁止自递归属性.
亚历克斯特纳
项目经理
Visual C#编译器
Eri*_*ert 13
除了Alex的解释之外,另一点是我们试图给代码做警告,这些代码执行了一些您可能不想要的事情,这样您就可能意外地发现了这个bug.
在这种特殊情况下,警告实际上会节省多少时间?单次测试运行.你在测试代码的那一刻就会发现这个bug,因为它总是会立即崩溃并且死得很厉害.这个警告实际上并没有给你带来太大的好处.在递归属性评估中存在一些微妙错误的可能性很低.
相比之下,如果您执行以下操作,我们会发出警告:
int customerId;
...
this.customerId= this.customerId;
Run Code Online (Sandbox Code Playgroud)
没有可怕的崩溃和死亡,代码是有效的代码; 它为一个字段赋值.但由于这是无意义的代码,你可能并不是故意这样做.因为它不会死得很厉害,所以我们会发出一个警告:这里有一些你可能不想要的东西,否则可能不会通过崩溃发现.
dbk*_*bkk 10
引用自身的属性并不总是导致无限递归和堆栈溢出.例如,这工作正常:
int count = 0;
public string Abc
{
count++;
if (count < 1) return Abc;
return "Foo";
}
Run Code Online (Sandbox Code Playgroud)
上面是一个虚拟示例,但我确信可以提出类似的有用递归代码.编译器无法确定是否会发生无限递归(停止问题).
在简单的情况下生成警告将是有帮助的.