在 SQLDataReader 上使用

问题描述 投票:0回答:2

我知道我之前问过相关问题。我只是有另一个想法。

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
,所以我需要将其放入。我是对的吗根据我的判断?)我只是感到困惑,因为它不是一个新对象,它会在处理仅是命令的引用指针的对象时导致任何问题吗?

c# dispose sqldatareader using-statement
2个回答
30
投票

我想你错了。

dr
是对
cmd.ExecuteReader
返回的对象的引用,这将是一个新对象。 在您的示例中,没有任何东西会处置
dr
,所以是的,它需要位于
using
中,或手动处置。

您对

IDisposable
实施者需要处于
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 
        } 
   } 
} 

2
投票

您应该将数据读取器包装在 using 语句中,因为 ExecuteReader 方法正在创建一个也应该被处置的新数据读取器实例。

© www.soinside.com 2019 - 2024. All rights reserved.