c# - 为什么编译器会提示 'not all code paths return a value' 而我可以清楚地看到他们这样做?

标签 c# compiler-errors static-analysis

我正在尝试弄清楚为什么编译器对该函数有问题。它给了我“并非所有代码路径都返回一个值”错误,但是我看不到控制流将传递给没有 aif( a ) 表达式的情况为真(因此 if( a ) 是多余的,但编译器似乎无法识别)。

public static Boolean Foo(Boolean x)
{
    Boolean a = false;
    if( x )
    {
        a = true;
    }
    else
    {
        try
        {
            SomethingThatMightThrow();
            Assert.IsFalse( a );
            return a;
        }
        catch(Exception)
        {
            a = true;
        }
    }

    if( a )
    {
        return x;
    }
}

直接的解决方法是简单地完全删除 if( a ) 保护语句并立即 return x - 但为什么编译器会提示,即使它应该能够静态证明所有可能的代码路径都会命中 return 语句?至关重要的是,没有循环,这通常是它无法证明 return-ness 的主要原因。

我正在使用 VS2015 更新 3。

最佳答案

有一个受支持的场景,当您到达函数末尾时,afalse。这种情况是当您调试代码并使用调试器 a 设置为false 时。

C# 编译器规则设计简单。在 C# 借鉴的语言中,函数可能不返回任何内容的问题是编译器警告无法涵盖的问题。误报太多,因此警告被调整为只警告明显的情况,引入误报。 C# 的规则是一种妥协,如果熟悉规则的人可以理解误报,那么误报是可以接受的,而误报是 Not Acceptable 。你可以保证,如果你的函数有一个不返回值的代码路径,编译器会检测到它。

这些简单规则的一部分是不考虑变量的值。即使 a 静态保证为 true,编译器在设计上也无法利用这一事实。

@PetSerAl 已经引用了C#语言规范中的相关措辞:

8.1 End points and reachability

[...]

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. In other words, for purposes of control flow analysis, a non-constant expression of a given type is considered to have any possible value of that type.

这是当前发布的最新语言规范的一部分,即 C# 5.0 的规范。您正在使用的版本 C# 6.0(这是 VS2015 提供的)尚未发布规范,因此措辞可能会略有不同,但正如您的编译器所显示的那样,实际上相同的规则仍然适用。

关于c# - 为什么编译器会提示 'not all code paths return a value' 而我可以清楚地看到他们这样做?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41777289/

相关文章:

java - SonarQube 与 FindBugs 插件

c# - 为什么我的 CSS 没有应用到 <asp :Linkbutton> having classCss property? 虽然它应用在一个简单的 HTML 按钮标签上

c# - 从 MVC Controller 使用 ASP.NET WebApi

C# 内存到 TextReader

c++ - 带有#include的C++未知重写说明符

go - 检查所有字段是否在结构初始化中显式设置的 Linter

c# - 通过远程桌面连接时出现 IValueConverter NullReferenceException

Java导入包不存在

c++ - 在 Mac OS 上将 Xcode 更新到最新版本后 "warning: section "__const_coal "is deprecated"错误

static-analysis - Elm 查找未使用的函数