为什么编译器对此代码的行为有所不同?

时间:2009-12-23 12:50:49

标签: c# compiler-errors

在C#中,以下方法无法编译:

public bool IsItTrue()
{
}

编译器错误:'IsItTrue()':并非所有代码路径都返回一个值,这非常有意义。但是下面的编译没有任何问题。

public bool IsItTrue()
{
    while (true)
    {
    }
}

哪个看起来不对,因为根本没有return语句。为什么会这样?这里有任何帮助......,

3 个答案:

答案 0 :(得分:13)

编译器知道第二种方法永远不会返回。

如果任何一种方法在任何情况下都返回,那么它们必须返回bool

第一种方法不包含任何无限循环,不抛出任何无条件异常等,因此必须返回bool。代码不返回bool,因此编译器拒绝编译它。

由于无限while (true)循环,第二种方法永远不会返回。如果从不返回,那么从不返回什么(如果有的话)并不重要,因此编译器将允许它进行编译。

编译器将识别并允许的更多示例:

public bool IsItTrue()
{
    throw new Exception("Always thrown!");
}

public bool HowAboutThisOne()
{
    if ((46 - 3) < (27 * 9))
    {
        throw new Exception("Always thrown!");
    }
}

答案 1 :(得分:3)

编译器错误消息很好地解释了第一个。

第二个永远不会返回,因此永远不会返回任何值。

不一样。在您的第一个示例中,该方法可以返回而不向调用者返回任何值 - &gt;编译错误。

第二个永远不会返回(编译器足够智能,它会发现你创建了一个无限循环)。它永远不会进入“好吧,我到达方法结束而不知道该返回什么状态。”

答案 2 :(得分:1)

Halting Problem表示您通常无法确定程序是终止还是永久运行。鉴于此线程中的示例似乎违反了此原则,我怀疑C#编译器正在对可以减少为编译时常量的循环条件执行分析。如果常量计算为true,那么我们就知道循环永远不会终止。

例如,请考虑以下两个函数。

public bool NoError()
{
    while (true) { }
}

public bool Error()
{
    while (NoError()) { }
}

如图所示,第一个函数不会生成编译时错误。但是,第二个因为编译器无法评估函数调用NoError()的结果。如果NoError()被修改为始终返回true,也会出现这种情况。