2010-08-02 47 views
11

我知道我之前問過一個相關的問題。我只是另有想法。在SQLDataReader上使用

using (SqlConnection conn = new SqlConnection('blah blah')) 
{ 
    using(SqlCommand cmd = new SqlCommand(sqlStatement, conn)) 
    { 
     conn.open(); 

     // *** do I need to put this in using as well? *** 
     SqlDataReader dr = cmd.ExecuteReader() 
     { 
      While(dr.Read()) 
      { 
       //read here 
      } 
     } 
    } 
} 

的論點是:由於SqlDataReaderdr對象不是一個新的對象像連接或命令對象,其簡單地指向cmd.ExecuteReader()方法的引用,是否需要把讀者using內部。 (現在基於我以前的帖子,我的理解是,任何使用IDisposable的對象都需要放在using中,並且SQLDataReader繼承自IDisposable,所以我需要說明,我的判斷是否正確?)我只是混淆,因爲它不是一個新的對象,它會導致處理一個對象的任何問題,只是一個引用指針的指針?

非常感謝

+0

「cmd.ExecuteReader」 是一種方法的參考。 「cmd.ExecuteReader()」(通知括號)是一個方法調用。 – 2010-08-02 10:20:49

回答

26

我想你錯了。 dr是對由cmd.ExecuteReader返回的對象的引用,它將成爲一個新對象。在你的例子中,什麼都不會配置dr,所以是的,它需要在using,或手動處理。

您對IDisposable執行者的判斷需要處於using不正確。他們將在室外運行良好。 A using陳述僅僅是try ... finally的語法糖。執行IDisposable的東西應該調用Dispose,因爲它們表明它們需要以確定性方式處理某些狀態。

請注意,如果您不撥打Dispose,它並不總是一個問題。一些對象也實現了終止器,它將由垃圾收集器觸發。如果他們沒有實現終結器,他們可能會留下未被管理的內存。在您的應用程序關閉之前,這將保持未復原狀態。所有託管內存最終都會回收,除非它不適合垃圾回收。

重新寫成:

using (SqlConnection conn = new SqlConnection('blah blah')) 
using(SqlCommand cmd = new SqlCommand(sqlStatement, conn)) 
{ 
    conn.open(); 
    using (SqlDataReader dr = cmd.ExecuteReader()) 
    { 
     while (dr.Read()) 
     { 
      //read here 
     } 
    } 
} 
+0

是的,我明白,使用簡單地轉化爲一個try..finally塊,我也可以稱之爲處置我的自我。但我認爲更好的做法是將這個塊封裝在使用中,因爲我可能會忘記將代碼塊放在try.finnally中。謝謝回覆。 :) – xeshu 2010-08-02 10:22:48

+0

沒關係:-)我會提及它,以及SqlDataReader是一個新對象,或者至少是方法調用返回的對象的引用,它不是對方法的引用。只是提到,因爲你用大寫字母表達了這一點,並且它不正確。閱讀器和連接/命令之間的唯一區別在於您已初始化連接/命令,但未初始化閱讀器。最後你仍然可以引用所有的對象 - 不管你是否初始化它們。 – 2010-08-02 10:25:41

+0

啊是的。我的錯! :) – xeshu 2010-08-02 10:29:59

2

爲ExecuteReader方法是創建也應設置一個新的數據讀取器的實例應該包裝數據讀取器using語句。