2

为什么在下面的代码中,.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.  

一旦你养成了翻译的习惯,我想一切都好。

4

5 回答 5

11

来自 Visual Studio 2010 附带的 C# 语言规范 4.0。

10.6.10“方法体”:

当方法的返回类型不是 void 时,该方法主体中的每个 return 语句都必须指定一个可隐式转换为返回类型的表达式。返回值的方法的方法体的端点不能到达。换句话说,在返回值的方法中,不允许控制从方法体的末尾流出。

可达性的定义在这里(强调添加):

8.1 “端点和可达性”:

如果一个语句有可能通过执行到达,则称该语句是可到达的。相反,如果一个语句不可能被执行,则该语句被称为不可达。

...

为了确定特定语句或端点是否可达,编译器根据为每个语句定义的可达性规则执行流分析。流分析考虑了控制语句行为的常量表达式(第 7.19 节)的值,但不考虑非常量表达式的可能值

由于!test不是一个常量表达式(即使它总是计算为true),编译器有义务在流分析中不考虑它。这种限制的一个原因(可能是唯一的原因)是在一般情况下执行这种流量分析是不可能的。

要消除错误,您需要在子句中或在方法末尾无条件地添加另一个return语句。else

于 2012-04-11T21:41:01.923 回答
10

来自Eric Lippert 的博客

可达性分析器不是很聪明。它没有意识到只有两种可能的控制流,并且我们已经用返回覆盖了所有它们。

(博客文章是关于switch语句的,但我猜可达性分析器对于if语句来说并没有那么聪明。)

于 2012-04-11T21:33:00.077 回答
3

这只是表示编译器在初始化什么以及将执行哪些行方面的智能限制。

我不时遇到这种情况。但很少有问题。我通常会稍微重构一下代码。

于 2012-04-11T21:31:08.497 回答
1

让我们向后分析代码:

问题:代码不返回任何值。

问题:在代码中的哪个位置返回值?

答:就在最后一行。

结论:所以那行代码(最后一行)应该总是返回一个值。

问题:最后一行是否总是返回一个值?

回答:不,只有在第一行设置为testis时才返回值。falsetrue

结论:正如编译器所说,这个函数在它应该返回时从不返回值bool

于 2012-04-11T21:46:47.603 回答
0

让我直接回答您的问题,而不是详细说明。

  1. 函数的返回类型指定为Bool ,因此该函数必须返回 True 或 false
  2. Param已被定义为输入参数,因此在编译时无法确定其值
  3. 测试变量的值取决于参数,根据步骤 2,参数值无法在编译时确定,因此测试值无法在编译时确定
  4. 由于 test 的值不称为编译时间(根据步骤 3),因此它开始为if (!test)寻找 else / default 根,因此它会引发错误。

谢谢

于 2018-08-14T12:36:24.457 回答