13

私は以前に関連する質問をしたことを知っています。私はちょうど別の考えを持っていました。

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
            }
        }
    }
}

引数は次のとおりです。SqlDataReader drオブジェクトは接続オブジェクトやコマンドオブジェクトのような新しいオブジェクトではないため、cmd.ExecuteReader()メソッドを指す単なる参照であるため、リーダーを。内に配置する必要がありますかusing。(以前の投稿に基づいて、を使用するオブジェクトはIDisposableに入れる必要がありusing、からSQLDataReader継承する必要があることを理解しているIDisposableので、それを入れる必要があります。私の判断で正しいですか?)新しいオブジェクトの場合、コマンドへの参照ポインタであるオブジェクトを破棄する際に問題が発生しますか?

どうもありがとう

4

2 に答える 2

30

あなたは間違っていると思います。はdr、 によって返されるオブジェクトへの参照でcmd.ExecuteReaderあり、新しいオブジェクトになります。あなたの例では、何も disposedrしないので、はいusing、または手動で破棄する必要があります。

IDisposable実装者がa にいる必要があるというあなたの判断usingは正しくありません。外でも問題なく機能します。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 
        } 
   } 
} 
于 2010-08-02T10:18:08.773 に答える
2

ExecuteReader メソッドは破棄する必要がある新しいデータ リーダー インスタンスを作成するため、データ リーダーを using ステートメントでラップする必要があります。

于 2010-08-02T10:17:23.517 に答える