为什么在代码中像下面是.NET编译器不能够确定,所有的代码路径都返回值?
bool Test(bool param) {
bool test = true;
if (param)
test = false;
else
test = false;
if (!test)
return false;
}
错误CS0161:并非所有的代码路径返回一个值!
该代码可以重构 - 但是编译器不提示。 然而,所有的返回路径覆盖 - 所以为什么编译器抱怨说,他们都没有?
编辑:我想这里的结论是:
(error CS0161) + (all code paths obviously return a value) => refactor code.
一旦你得到翻译的习惯,我想一切正常。
从包含在Visual Studio 2010中的C#语言规范4.0。
10.6.10“法体”:
当一个方法的返回类型不是void,在该方法的身体每一个return语句必须指定隐式转换为返回类型的表达式。 一个返回值的方法的方法体的端点必须是不可到达的。 换句话说,在一个返回值的方法时,控制不允许流出方法体的端部。
可达性的定义是在这里(强调):
8.1“结束点和可到达”:
如果一个语句可能通过执行来达到,该声明被认为是可达的。 反之,如果没有一个语句将被执行的可能性,该声明被认为是不可到达的。
...
为了确定一个特定语句或结束点是否可到达,编译器根据为每个语句中定义的可达性规则流分析。 流分析考虑到控制语句行为的常量表达式(§7.19)的值,但非恒定表达的可能值不考虑 。
由于!test
不是一个常量表达式(即使它会始终评估为true
),编译有义务不考虑它的流动分析。 原因之一(也许是唯一的原因),这种限制是进行这种类型的流量分析,在一般情况下是不可能的。
为了摆脱错误的,你需要有另一种return
声明,无论在else
无条件地在方法的最后条款或。
从埃里克利珀的博客 :
可达性分析是不是很聪明。 它没有意识到,只有两种可能的控制流,我们已经覆盖了所有他们与回报。
(本博客文章是对switch
语句,但我估计可达性分析是不是要聪明得多if
报表。)
这只是表示该编译器是多么聪明关于什么被初始化和线路将执行的限制。
我碰到这样不时。 但它很少,这是一个问题。 我通常只重组代码一点。
让我们落后的分析代码:
问题:代码不返回任何值。
问:凡在代码返回一个值?
答:就在最后一行。
结论:所以代码(最后一行)的该行应该总是返回一个值。
问:请问最后一行总是返回一个值?
答:不,它只有返回值test
是false
,而它已经被设置为true
在第一线。
结论:由于编译器说,虽然它应该返回这个函数永远没有返回值bool
。