it-swarm-ru.tech

Foreach автоматически вызывает Dispose?

В 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();
}
57
jim

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

49
Matt H

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

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

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

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

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

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

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

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

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

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

12
Stuart Frost