2010-01-12 190 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)」和缺少中斷意味着循環從不「離開底部」,因此方法的終點不可達。什麼錯誤「不是所有的代碼路徑返回一個值」實際上意味着是「存在一個代碼路徑退出方法,但不返回一個值」。它確實是而不是的意思是「有一個代碼路徑永遠運行」 - 因爲找出這個問題涉及到解決停機問題。

相關問題