2012-06-07 112 views
0

是否相同,當我用這個:異常構造類

catch(Exception e) 
{ 
    throw new Exception("some Exception", e); 
} 

這:

catch(Exception e) 
{ 
    throw new Exception("some Exception", e.InnerException); 
} 

或迪我失去了一些東西?

回答

5

在第二個示例中,您將放棄捕獲的異常,而是使用其內部異常。您通常會按照第一個示例中的代碼進行編碼。

在第一種情況下,捕捉到的異常(e)成爲新的異常的InnerException你扔:

catch(Exception e) 
{ 
    throw new Exception("some Exception", e); 
} 

在第二種情況下,你正在使用的eInnerException,並從e數據丟失:

catch(Exception e) 
{ 
    throw new Exception("some Exception", e.InnerException); 
} 
+0

換句話說,我放棄包含在對象e中的異常? – Jorge

+0

@Jorge - 是的,這是正確的。 – Oded

3

第一個示例通常說得更正確。當你拋出一個新的異常作爲另一個異常的結果時,你應該包括原始內容作爲新的異常。

雖然這並非普遍。它可以在一些非常特殊的情況下,你想撤銷另一個代碼的真正的錯誤包裝是有用的。

try { 
    // some reflection call 
} catch (TargetInvocationException e) { 
    // Reduce the layers of data a developer has to dig through by using the real 
    // exception when I re-wrap 
    throw new MyException("some message", e.InnerException); 
} 
2

有三種方法重新拋出異常:

catch (Exception ex) 
{ 
    throw; 
} 

拋出與保存的原始堆棧跟蹤原始異常。

catch (Exception ex) 
{ 
    throw ex; 
} 

拋出原始異常,但原始堆棧跟蹤丟失。堆棧跟蹤現在將此行顯示爲異常的發起者。

catch (Exception ex) 
{ 
    throw new Exception("...", ex); 
} 

拋出一個新的異常,但保留了原來的異常和堆棧跟蹤新的異常的InnerException

第一種情況是有用的,你需要清理失敗,但不成功。如果你需要在兩種情況下清理,你可以使用finally子句,而不是catch子句。或者你只是想記錄這裏發生的異常,並讓調用者處理它。

第二種情況根本沒有用。你爲什麼隱藏堆棧跟蹤?可能有一些罕見的情況,這是有用的,但我知道沒有。

第三種情況最常用於想要返回單一類型的異常(或類型族)。例如,您是一種文本解析方法,您希望所有(非致命)異常轉換爲ParseException(或其他任何形式),以提供其他細節,如發生異常的文本中的行號。

在您提供的第二個示例中,被捕獲的異常完全被丟棄。生成新的異常,並且原始異常的InnerException成爲此新異常的InnerException。我可以想象沒有任何情況下剝離中間例外是有用的。