Foreach автоматически вызывает Dispose? - PullRequest
57 голосов
/ 13 февраля 2011

В C #, foreach автоматически вызывает Dispose для любого объекта, реализующего IDisposable?

http://msdn.microsoft.com/en-us/library/aa664754(v=vs.71).aspx, кажется, указывает, что это делает:

* В противном случае выражение коллекции имеет тип, который реализует System.IEnumerable, и расширение оператора foreach выглядит так: Копирование

IEnumerator enumerator = 
        ((System.Collections.IEnumerable)(collection)).GetEnumerator();
try {
   while (enumerator.MoveNext()) {
      ElementType element = (ElementType)enumerator.Current;
      statement;
   }
}
finally {
   IDisposable disposable = enumerator as System.IDisposable;
   if (disposable != null) disposable.Dispose();
}

Ответы [ 2 ]

49 голосов
/ 13 февраля 2011

Да, foreach будет вызывать Dispose () для перечислителя, если он реализует IDisposable.

12 голосов
/ 28 апреля 2014

Этот вопрос / ответ плохо сформулирован.

Непонятно, задан ли вопрос:

Q: "Располагает ли foreach объекты, возвращаемые перечислителем, до перехода к следующему?"

A: Ответ, конечно, НЕТ.Он ничего не делает, кроме того, что предоставляет удобный способ запуска некоторого кода один раз для каждого объекта в перечислении.

Или это означает:

Q: "Под капотом foreach использует перечисляемый объект.Размещается ли это после вызова foreach, даже если в блоке итератора есть исключение? "

A: Ответ (все еще довольно очевидно) ДА!Поскольку синтаксис не предоставляет вам доступ к перечислителю, он несет ответственность за его удаление.

Ответ на второй вопрос заключается в том, где возникает путаница, поскольку люди слышали, что foreach расширяется до временного блока сблок try / finally.Наконец, цель этого состоит в том, чтобы гарантировать, что перечислитель будет удален, если он реализует IDisposable.

В случае, если вам нужно увидеть это для себя: Смотрите это в действии здесь

Надеюсь, это поможет уточнить!;)

...