.NET 编译器和“并非所有代码路径都返回值" [英] .NET compiler and "Not all code paths return a value"

查看:33
本文介绍了.NET 编译器和“并非所有代码路径都返回值"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆