2009-07-07 26 views
4

如果ExecuteReader引發異常,我如何確定在IDataReader處置的以下代碼片段中?如果using語句引發異常,我該如何處理一個IDisposable對象?

using (IDataReader rdr = cmd.ExecuteReader()) 
{ 
    // use it 
} 

這對我來說很有意義的using語法糖不調用Dispose(因爲沒有實例,調用它)。但是,我怎樣才能確定通常由實現IDisposable的類分配的稀有資源將會被釋放?

+5

如果ExecuteReader引發異常,則IDataReader爲null並且不需要配置。 ExecuteReader中的非託管資源需要清理,並且應該在自己的finally塊中處理。 – cjk 2009-07-07 08:43:22

回答

14

如果ExecuteReader在你的例子中引發了一個異常,它永遠不會返回任何東西。然後由ExecuteReader的實現來處理在異常之前創建的任何東西。

-2

我認爲using語句被翻譯到類似於IL:

try 
{ 
} 
finally 
{ 
    disposableUsedObject.Dispose(); 
} 

所以,我認爲,在正常情況下,處置應該叫什麼名字?

另外,您不應該在構造函數內拋出異常,因爲用戶不會期望在實例化對象時拋出異常。 我會將可以拋出異常的初始化邏輯移動到實例化對象後必須調用的另一個方法(Initialize)。

+1

但是,如果構造函數拋出異常,沒有對象來處理? – cjk 2009-07-07 08:42:05

+0

@ck完全是我的問題 – jpoh 2009-07-07 08:43:02

+0

您不應該在構造函數中拋出異常,因爲這有點意外。你的類的用戶不希望在實例化一個對象時可以在構造函數中拋出異常。 :) 我認爲最好移動該初始化邏輯(可以顯示另一個方法的異常(初始化,或類似的東西) – 2009-07-07 08:47:10

3

如果對象的構造函數無法運行,那麼您沒有需要處理的對象。

如果您正在編寫可能會引發異常的構造函數,最好通過使用using或try-catch塊來確保清理所需的任何內容。

在您的IDataReader示例中,如果cmd.ExecuteReader()方法調用失敗,只需處理命令對象就足夠了。

0

如何將在構造函數外執行初始化的代碼移動到單獨的函數中。實質上,您將擁有

using (var tc = new TestClass()) 
{ 
    tc.Initialize(); // setup the object. acquire expensive resources here, etc. 

    ..more code .. 
} 
相關問題