2009-06-28 57 views
1

在Delphi中,如果在構造對象期間發生異常:任何分配的內存將被釋放並引發異常。例如,下面是保證要麼返回一個有效的Camera對象,或者拋出一個異常:CLR:如果構造函數失敗,它總是會拋出異常?

Camera c = new Camera(); 

從未必須檢查所生成的變量爲空:

Camera c = new Camera(); 
if (c == null) 
    throw new Exception("Error constructing Camera") //waste of time 

在CLR中也是如此嗎?

還有其他的合成結構,其中返回值保證有效,或拋出異常?

  • 創建結構(例如Rectangle)?
  • 獲取枚舉的成員?
  • Object.ToString()的結果?
  • mathmatical operations?

在執行數學的情況下:

Int32 aspect = 1650.0/1080.0; 
if (aspect == null) 
    throw new Exception("Division of two numbers returned null") 

回答

3

.Net中的構造函數保證返回該對象類型的非空實例。實例是否爲有效取決於該類型的單個語義。

在構造函數中引發的異常不會被CLR任意吞噬(雖然用戶代碼可以吞下它們)。CLR將像在其他方法中拋出的異常一樣傳播異常,並且對象最終會被正確地垃圾收集。

至於其他的情況下,你提到

  • 創建結構:通過定義結構永遠不能爲空。拋出在構造函數中的異常將正常傳播
  • 獲取枚舉成員:枚舉是引擎蓋下的結構/值類型,也不會爲空
  • Object.ToString()的結果:This can(並可悲地將)爲空。 String是一個引用類型,從ToString覆蓋返回null是完全合法的(請不要)。
  • 數學運算:這很大程度上取決於項目的溢出設置和正在使用的特定類型(積分與浮點數)。

數學問題幾乎值得自己回答。一方面,基元類型的數學運算的結果不會爲空。但它仍然可能是無效的。例如,下面的代碼不會拋出,但是否將結果是有效的高度上您的具體方案

float f1 = 1.0; 
float f2 = f1/0; 

取決於此時f2是,並不代表真正的數量非常具體的浮點值。它有效嗎?取決於你的用例。

1

是。我想這樣說(因爲失敗可能意味着邏輯失敗):如果構造函數沒有拋出異常,返回值保證爲非null,所以你永遠不必執行這樣的一張支票。

創建結構(例如矩形):一個struct不能null在所有(Nullable類型被認爲是完全不同的類型,即typeof(int?) != typeof(int))。調用結構的構造函數可能會因拋出異常或返回實例而失敗。

獲取枚舉成員:enum只是一組常量。沒有什麼比「在運行時獲得成員」更好。它在編譯時被替換。

Object.ToString()結果:其他任何方法一樣,它可以爲string類型,其中包括null,還可能拋出一個異常(在這種情況下,它不會返回一個值的話)返回任何有效的值。

數學運算:所有表達式都會返回一個值或拋出異常。返回值可以是該類型的任何有效值(例如Int32永遠不可以是null)。

相關問題