2010-01-12 176 views
3

这是代码:为什么在这种情况下编译器不会抱怨?

private TreeNode GetTopLevelNode(TreeNode childNode) 
    { 
     if (childNode == null) 
      throw new ArgumentNullException("childNode", "childNode is null."); 

     if (childNode.Parent == null) return childNode; 

     TreeNode node = childNode; 
     while (true) 
     { 
      if (node.Parent == null) 
      { 
       return node; 
      } 
      node = node.Parent; 
     } 

    } 

while循环,只有当node.Parent == null,则节点将被退回,

为什么编译器不会报告“并非所有的代码路径返回一个值“错误?

如果无法满足'node.Parent == null',则不会返回树节点。 编译器无法检测到这种情况?

+0

我认为你的代码中存在一个bug:在while循环中:你不应该返回节点而不是node.Parent? – 2010-01-12 06:50:28

+0

@Tommy,感谢您指出 – Benny 2010-01-12 06:54:23

回答

10

由于您使用的是while(true){,除了使用返回外,没有其他方式可以退出循环。如果node.parent == null不能满足,那么它将是一个无限循环。因此,没有办法在没有返回的情况下越过循环,编译器不会抱怨。

此外,您指定的代码将几乎总是返回一个空值TreeNode,这是你真正想要的吗?

编辑:我看到你修好了。

+0

智能编译器。 – 2010-01-12 18:12:50

1

编译器很智能并且优化了你的循环。它知道唯一的出路是在if (node.Parent == null)条件返回true后返回。

1

除非你有一个无限深度循环这段时间将永远持续下去。

因此,无论循环会卡住还是在某个点上,Parent都将为空。它不会在这段时间后进入,因为它不会结束。

1

编译器意识到函数将在所有终止的情况下返回一个TreeNode。在函数返回的所有情况下,它将返回一个适当的值。因此,没有任何情况下会返回未定义的值,编译器也没有发现警告的理由。

如果函数没有返回,那么在想知道返回值时没有用处。

9

你的问题实际上是计算机科学中最深入和最有趣的问题之一。这个问题被称为停机问题:给定一个程序的问题决定了它是否总是返回或永远运行。

停机问题是有名的,因为它可以证明不能通过计算机解决。没有算法可以可靠地告诉你一个给定的程序是否停止。你可以证明这样一个程序(1)给出了错误的答案,(2)不能分析所有的程序,或者(3)自己有时从不停止。

因此,C#编译器不会尝试解决暂停问题。相反,我们只是检测到“while(true)”和缺少中断意味着循环从不“离开底部”,因此方法的终点不可达。什么错误“不是所有的代码路径返回一个值”实际上意味着是“存在一个代码路径退出方法,但不返回一个值”。它确实是而不是的意思是“有一个代码路径永远运行” - 因为找出这个问题涉及到解决停机问题。

相关问题