Подтвердить что ты не робот

Использование на 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
            }
        }
    }
}

Аргумент таков: поскольку объект SqlDataReader dr НЕ является НОВЫМ ОБЪЕКТОМ, КАК ОБЪЕКТОМ или командами, его просто ссылкой, указывающей на метод cmd.ExecuteReader(), нужно ли вводить читателя внутри using. (Теперь, основываясь на предыдущем сообщении, я понимаю, что любой объект, который использует IDisposable, должен быть помещен в using, а SqlDataReader наследуется от IDisposable, поэтому мне нужно его поместить. на мой взгляд?) Я просто смущен, так как это не новый объект, может ли это вызвать проблемы с удалением объекта, который просто является ссылочным указателем на команду?

Большое спасибо

4b9b3361

Ответ 1

Я думаю, вы ошибаетесь. 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 создает новый экземпляр для чтения данных, который также должен быть удален.