【问题标题】:Why compiler behaves differently with this code?为什么编译器对这段代码的行为不同?
【发布时间】:2009-12-23 12:50:49
【问题描述】:

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

public bool IsItTrue()
{
}

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

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

这看起来是错误的,因为根本没有返回语句。为什么会这样?这里有任何帮助...,

【问题讨论】:

    标签: c# compiler-errors


    【解决方案1】:

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

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

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

    第二种方法永远不会返回,因为无限的while (true) 循环。如果它 never 返回,那么 never 返回什么(如果有的话)都没有关系,因此编译器将允许它编译。

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

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

    【讨论】:

    • 有趣的是编译器会允许这样做。我可以理解为什么它可以被允许,但我想知道它的实际用途是什么。
    • 我知道我们可能想要一个类似于 while(true) 的线程,但即使线程也应该在某个时候结束?那么如果编译器可以检测到这种情况,为什么它不抛出一个错误点一个无限循环呢?
    • 这是可行的,因为循环或条件表达式可以在编译时进行评估。在此线程中查看我的答案:stackoverflow.com/questions/1952634/…
    【解决方案2】:

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

    第二个从不返回,所以从不返回任何值。

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

    第二个永远不会返回(编译器足够聪明,它发现你创建了一个无限循环)。它永远不会进入“好的,我已经到了方法的末尾,不知道要返回什么”状态。

    【讨论】:

      【解决方案3】:

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

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

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-07-06
        • 2013-08-08
        • 1970-01-01
        • 2014-09-14
        • 2011-11-27
        • 2010-10-24
        相关资源
        最近更新 更多