为什么在如下代码中,.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.
一旦你养成翻译的习惯,我猜一切都还可以。
答案 0 :(得分:11)
来自Visual Studio 2010附带的C#语言规范4.0。
10.6.10“方法体”:
当方法的返回类型不为void时,每个return语句都在 该方法的主体必须指定隐式表达式 可转换为返回类型。方法体的端点 值返回方法不能被访问。换句话说,在一个 值返回方法,控制权不允许流出结束 方法体。
reachability 的定义在这里(强调添加):
8.1“终点和可达性”:
如果执行可能达到语句,则语句为 据说可以到达。相反,如果没有可能性 声明将被执行,声称该声明无法访问。
...
确定特定语句或结束点是否可达, 编译器根据可达性执行流分析 为每个陈述定义的规则。流量分析考虑在内 控制行为的常量表达式(第7.19节)的值 语句,但非常量表达式的可能值 不被视为。
由于!test
不是常量表达式(即使它总是计算为true
),编译器也不得在流分析中考虑它。这种限制的一个原因(可能是唯一的原因)是在一般情况下进行这种流量分析是不可能的。
要消除错误,您需要在return
子句中或在方法结束时无条件地使用另一个else
语句。
答案 1 :(得分:10)
可达性分析仪不是很聪明。它没有意识到只有两种可能的控制流,并且我们已经用返回覆盖了所有这些流。
(博客帖子在switch
语句中,但我认为可达性分析器对于if
语句来说并不聪明。)
答案 2 :(得分:3)
这只是表示编译器在初始化内容以及将执行哪些行方面的智能限制。
我不时遇到这种情况。但它很少是一个问题。我通常会稍微调整一下代码。
答案 3 :(得分:1)
让我们向后分析代码:
问题:代码不会返回任何值。
问题:代码中返回值的位置是什么?
答案:就在最后一行。
结论:因此代码行(最后一行)应始终返回一个值。
问题:最后一行是否总是返回值?
答案:不,只有当test
为false
且true
在第一行设置为bool
时,它才会返回值。
结论:正如编译器所说,这个函数在返回{{1}}时永远不会返回值。
答案 4 :(得分:0)
让我直接回答您的问题,而不是详细介绍。
谢谢