这是代码:
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 :(得分:10)
因为你使用while(true){
,除了使用return之外没有其他方法可以退出循环。如果node.parent == null
不能满足,那么它将是一个无限循环。因此,没有返回就无法通过循环,编译器也不会抱怨。
此外,您指定的代码几乎总是返回null TreeNode
,这是您真正想要的吗?
编辑:我看到你解决了这个问题。
答案 1 :(得分:9)
您的问题实际上是计算机科学中最深刻,最有趣的问题之一。这个问题被称为停机问题:给定一个程序的问题,确定它是否总是返回或永远运行。
暂停问题很有名,因为它可以证明无法通过计算机解决。没有算法能够可靠地告诉您给定的程序是否停止。您可以证明这样的程序要么(1)给出错误答案,(2)不能分析所有程序,要么(3)本身有时永远不会停止。
因此C#编译器不会尝试解决停机问题。相反,我们只是检测到“while(true)”和缺少中断意味着循环永远不会“离开底部”,因此方法的终点是不可达的。错误“并非所有代码路径返回值”实际上意味着是“存在退出方法但不返回值的代码路径”。它确实不意味着“有一个永远运行的代码路径” - 因为搞清楚是为了解决停机问题。
答案 2 :(得分:1)
编译器非常智能,可以优化循环。它知道唯一的出路是在if (node.Parent == null)
条件返回true
之后返回。
答案 3 :(得分:1)
除非你有无限深度或循环,否则会永远持续下去。
因此,循环将被卡住或在某些时候,父将为空。它永远不会进入,因为它不会结束。
答案 4 :(得分:1)
编译器意识到函数将在它将终止的所有情况下返回TreeNode
。在函数返回的所有情况下,它将返回适当的值。因此,没有返回未定义值的情况,编译器也没有看到警告的理由。
如果函数没有返回,则不知道返回值。