Подтвердить что ты не робот

Может ли foreach автоматически вызывать Dispose?

В С#, 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();
}
4b9b3361

Ответ 1

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

Ответ 2

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

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

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

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

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

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

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

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

Если вам нужно это увидеть самостоятельно: Посмотрите на него здесь

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