Короче говоря, вам не нужно об этом беспокоиться, пока вызывающая сторона метода правильно обрабатывает объекты IEnumerator
.
IEnumerator
реализует IDisposable
, и логика, используемая при создании блоков итератора, на самом деле достаточно умна, чтобы выполнять все невыполненные блоки finally при их удалении. В результате вызова using
создается блок finally, в котором размещается ресурс IDisposable
.
Таким образом, пока объекты IEnumerator
, созданные из этого IEnumerable
, либо полностью повторяются (в этом случае последний вызов MoveNext
достигнет конца блока using
и избавится от ресурса), либо будут удалены, клиент IDisposable
будет удален.
Обратите внимание: если вы обеспокоены тем, что пользователь вашего кода может неправильно обрабатывать объекты IEnumerator
, лучше всего не использовать блок итератора с ленивой оценкой. Если вы хотите убедиться, что даже если вызывающий объект не "играет хорошо", то с нетерпением оцените метод (т.е. возьмите код, который у вас есть, выгрузите результаты в список, а затем верните этот список). Если последствия неутилизации ресурса в первую очередь или полностью связаны с производительностью (неосвобождение некоторой памяти в течение некоторого времени, сохранение открытого соединения и т. д.), то это может не вызывать беспокойства, но если постоянное удержание блокировки является серьезная проблема (например, заблокированный ресурс, который может привести к взаимоблокировкам, если его не освободить), то преимущество ленивых вычислений может не стоить того.
person
Servy
schedule
22.11.2012
using
, и никто не называет его плохим, но никто не объясняет, что это нормально (или почему это нормально), насколько я могу судить. - person Servy   schedule 22.11.2012IEnumerable<IEnumerable<string>>
. Я полагаю, это не то, что вы имели в виду. - person svick   schedule 22.11.2012yield
Выбирать изusing
- плохая идея, потому что вызывающие абоненты, которые неDispose()
пересчитывают счетчик, запутают вас. - person SLaks   schedule 22.11.2012