JSB*_*ոգչ 1 c# code-analysis for-loop exception
我有以下(简化)方法:
public bool DoWorkWithRetry()
{
for (int remainingTries = Constants.MaxRetries; remainingTries >= 0; remainingTries--)
{
try
{
return DoWork();
}
catch (Exception ex)
{
if (remainingTries == 0)
{
throw new WorkException(
String.Format("Failed after {0} retries.", Constants.MaxRetries),
ex);
}
// fall through to retry
}
}
}
Run Code Online (Sandbox Code Playgroud)
我觉得这个方法要么退还要么抛出.但是,C#编译器向我抱怨not all code paths return a value
.
for
循环可以完成没有投掷或返回?Jon*_*eet 12
编译器只是遵循语言规范.
该语言并没有尝试执行的"如果你开始一个整数,并多次减一,你总会最终击中在一些点零"的分析.这甚至假设它Constants.MaxRetries
是一个编译时常量.
基本上,语言规范具有可达性规则- for
如果其中任何一个为真,则可以访问语句的结束点(C#4规范的第8.8.3节):
for
语句包含break
退出for
语句的可访问语句for
语句是可达的,并且存在for-condition并且没有常量值true
后一点是这里的情况,因此for
语句的结尾是可达的.不允许非void方法的结束,因此错误.(C#规范第8.1节)
另一种方法是使语言变得更加复杂.我完全可以不用编译.
编译器不知道for循环将始终至少执行一次.它认为它是一个永远不会运行的有效选项,在这种情况下它不会throw
或return
.
虽然通过对程序进行足够复杂的分析,理论上可以证明它总是返回或抛出,但这种分析非常复杂且性能密集.C#编译器团队不想冒错误的风险,或者考虑大幅增加编译时间以添加这种复杂的分析.他们选择使用更简单的"可达"和"无法访问"代码定义,这些代码更容易实现.
至于实际修复,只需throw
在方法的最后添加一个,并可能放入一条注释,说明实际上无法点击它.