Что лучше и когда: использование оператора или вызов Dispose () для IDisposable в C #?

Предположим, у меня есть следующее:

using(var ctx = DataContextFactory.Create(0))
{ ... Some code ... }

Почему бы просто не сделать следующее и не потерять пару фигурных скобок ?:

var ctx = DataContextFactory.Create(0);
ctx.Dispose();

Спасибо за совет!


person mkelley33    schedule 23.06.2009    source источник


Ответы (5)


Первое лучше. Он обеспечивает удаление, даже если возникает исключение, и правильно обрабатывает случай, когда Create(0) возвращает значение null (т. Е. Не пытается вызвать Dispose() в экземпляре NULL).

person Marc Gravell    schedule 23.06.2009
comment
Спасибо! Это был именно тот ответ, который я искал. - person mkelley33; 23.06.2009
comment
Дополнительный второстепенный момент, о котором никто не упомянул, заключается в том, что использование using предотвращает случайное изменение содержимого переменной ctx после ее инициализации, но до ее удаления. Вы не хотите, чтобы случайно удалили объект, отличный от созданного вами. - person Eric Lippert; 24.06.2009

Заявление using всегда лучше, потому что ...

  • вы не можете забыть вызвать Dispose(), даже если код превращается в разные пути кода
  • Dispose() вызывается даже в случае исключения. Он также проверяет null перед вызовом Dispose(), что может быть полезно (при условии, что вы не просто вызываете new).

Один неочевидный (во всяком случае для меня) трюк с using - как избежать чрезмерного вложенности, когда у вас есть несколько одноразовых объектов:

using (var input = new InputFile(inputName))
using (var output = new OutputFile(outputName))
{
    input.copyTo(output);
}

Средство форматирования кода VS оставит два оператора, начинающиеся в одном столбце.


Фактически, в некоторых ситуациях вам даже не нужно повторять оператор using ...

using (InputFile input1 = new InputFile(inputName1), input2 = new InputFile(inputName2))

Однако здесь действуют ограничения на объявление нескольких переменных в одной строке, поэтому типы должны быть одинаковыми, и вы не можете использовать неявный тип var.

person Trevor Robinson    schedule 23.06.2009

Где можно, используйте using по причинам, которые цитирует Марк. OTOH - это не мертвое решение, поскольку иногда время жизни объекта не может быть определено как лексическая область видимости, поэтому используйте его разумно.

person BCS    schedule 23.06.2009

Единственное место, где вы не хотите использовать блок using, - это место, где одноразовый объект находится за пределами функции. В этом случае ваш класс должен реализовать IDisposable и избавиться от объекта в его Dispose ().

person Jon B    schedule 23.06.2009
comment
Я встречал случаи, когда время жизни объекта короче, чем время жизни владельца. - person BCS; 23.06.2009

Оператор using дает хороший синтаксис плюс защиту от исключений. Вы не можете оставить оператор using без вызова Dispose (он преобразуется в блок finally с вызовом для удаления). Во втором сценарии, если бы у вас было исключение между Create и Dispose, вы не вызывали бы dispose напрямую. Это не проблема, если вы не используете неуправляемые ресурсы, но если да, то произойдет утечка.

person JP Alioto    schedule 23.06.2009