.NET 编译器和“并非所有代码路径都返回值" [英] .NET compiler and "Not all code paths return a value"
问题描述
为什么在下面的代码中,.NET 编译器无法确定所有代码路径都返回一个值?
bool 测试(bool 参数){布尔测试 = 真;如果(参数)测试 = 假;别的测试 = 假;如果(!测试)返回假;}
错误 CS0161:并非所有代码路径都返回值!
代码可以重构——但编译器不建议重构.然而,所有的返回路径都被覆盖了——那么为什么编译器会抱怨它们没有呢?
我想这里的结论是:
(error CS0161) + (所有代码路径显然都返回一个值) =>重构代码.
一旦你养成了这种翻译的习惯,我想一切都会好起来的.
来自 Visual Studio 2010 中包含的 C# 语言规范 4.0.
<块引用>10.6.10方法体":
当一个方法的返回类型不为void时,每个return语句在该方法的主体必须指定一个隐式的表达式可转换为返回类型.方法体的端点值返回方法必须不可访问.换句话说,在一个返回值方法,控件不允许流到最后方法体.
可达性的定义在这里(强调):
<块引用>8.1端点和可达性":
如果一个语句可以通过执行到达,则该语句为据说可以到达.相反,如果不可能语句将被执行,该语句被称为不可达.
...
要确定特定语句或终点是否可达,编译器根据可达性进行流分析为每个语句定义的规则.流量分析考虑控制行为的常量表达式(第 7.19 节)的值语句,但非常量表达式的可能值不考虑.
由于 !test
不是一个常量表达式(即使它总是评估为 true
),编译器不得不在流分析中不考虑它.这种限制的一个原因(可能是唯一的原因)是在一般情况下不可能执行这种流分析.
要消除错误,您需要在 else
子句中或在方法末尾无条件地添加另一个 return
语句.>
Why in code like below is the .NET compiler not able to establish that all code paths do return a value?
bool Test(bool param) {
bool test = true;
if (param)
test = false;
else
test = false;
if (!test)
return false;
}
error CS0161: Not all code paths return a value!
The code can be refactored - but the compiler is not suggesting that. Yet all return paths are covered - so why does the compiler complain that they are not?
Edit: I guess the conclusion here is that:
(error CS0161) + (all code paths obviously return a value) => refactor code.
Once you get the habit of that translation I guess everything is ok.
From the C# Language Specification 4.0 included with Visual Studio 2010.
10.6.10 "Method body":
When the return type of a method is not void, each return statement in that method’s body must specify an expression that is implicitly convertible to the return type. The endpoint of the method body of a value-returning method must not be reachable. In other words, in a value-returning method, control is not permitted to flow off the end of the method body.
The definition of reachability is here (emphasis added):
8.1 "End points and reachability":
If a statement can possibly be reached by execution, the statement is said to be reachable. Conversely, if there is no possibility that a statement will be executed, the statement is said to be unreachable.
...
To determine whether a particular statement or end point is reachable, the compiler performs flow analysis according to the reachability rules defined for each statement. The flow analysis takes into account the values of constant expressions (§7.19) that control the behavior of statements, but the possible values of non-constant expressions are not considered.
Since !test
isn't a constant expression (even though it will always evaluate to true
), the compiler is obliged to not consider it in the flow analysis. One reason (maybe the only reason) for this restriction is that performing this kind of flow analysis is impossible in the general case.
To get rid of the error, you'll need to have another return
statement, either in an else
clause or unconditionally at the end of the method.
这篇关于.NET 编译器和“并非所有代码路径都返回值"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!