2014-03-24 100 views
3

它再次是星期一,我有一個關於C#基礎的問題。如果方法拋出異常,那麼方法的返回值會發生什麼?如果方法拋出異常,則返回值返回值

具體來說,當一個方法內部拋出一個異常並且對返回值有什麼影響時,「引擎蓋下」會發生什麼?在這種情況下,內部計算的返回值如何?

假設有兩種情況:一種是返回值類型爲int,另一種是object。發生異常時,內部是否會調用default(T)?在這種情況下,我應該認爲int類型的返回值爲零,而對象的返回值爲null

回答

8

簡短,簡單的答案是它不會返回任何東西。代碼在任何發生異常的地方都會「中斷」,並且它會一直處於堆棧狀態,直到出現異常。

即使你碰巧趕上例外,你試圖用方法的返回值初始化將繼續它以前的方法被稱爲變量:

var i = 5; 

try 
{ 
    i = MyMethodThatThrowsAnException(); 
} 
catch 
{ 
    // at this point, the i variable still equals 5. 
} 

我應該提到你如果拋出異常,真的不應該擔心函數的返回值。如果你這樣做,那麼你可能會做錯某些事情,比如使用exceptions as flow control

+0

如果我這樣做'INT I =的MyMethod()'什麼將是返回值呢? –

+1

@devhedgehog同樣在這裏:函數不會返回,因此你的變量將不會被初始化。事實上,即使是在這種情況下你甚至不能使用這個值,因爲這個異常會導致代碼跳到它所發現的第一個catch塊,超出了聲明的變量範圍。 – Crono

2

作出的一項重大簡化:

當一個異常被拋出,.NET CLR開始搜索備份堆棧,直到它找到一個異常處理程序可以處理該異常。

此時,調整堆棧指針,以便異常處理代碼以正確的參數從正確的點運行。 (這個例外本身捕獲了擲骰點處的堆棧信息以使得該信息在捕獲點處可用)。

實際上,CLR執行了一種跳過任何代碼的「goto」使用拋出異常的函數的任何返回值 - 所以返回值根本就不相關。在這種情況下永遠不會創建,使用或需要它。

請注意,這是對實際發生的事情的大量簡化,但要避免的主要原因是出現了一種複雜的goto - 遍歷堆棧幀 - 。這就是返回值無關緊要的原因。

See this article for full details.