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

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

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

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

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

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

5 ответов


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


A 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.


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


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


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