Ответ 1
Да, foreach вызовет Dispose() в перечислителе, если он реализует IDisposable.
В С#, 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();
}
Да, foreach вызовет Dispose() в перечислителе, если он реализует IDisposable.
Этот вопрос/ответ плохо сформулирован.
Неясно, задан ли вопрос:
Q: "Предоставляет ли foreach объекты, возвращаемые перечислителем, перед переходом к следующему?"
A: Ответ, конечно, нет. Он ничего не делает, кроме как обеспечить удобный способ запуска некоторого кода один раз для каждого объекта в перечислении.
Или это означает:
Q: "Под капотом foreach использует перечислимый объект. Удаляет ли это после вызова foreach, даже если в блоке итератора есть исключение?"
A: Ответ (еще довольно очевидно) ДА! Поскольку синтаксис не предоставляет вам доступ к перечислителю, он несет ответственность за его удаление.
Ответ на второй вопрос заключается в том, где возникает путаница, поскольку люди слышали, что foreach расширяет блок while с помощью блока try/finally. Цель этого заключается в том, чтобы обеспечить, чтобы перечислитель располагался, если он реализует IDisposable.
Если вам нужно это увидеть самостоятельно: Посмотрите на него здесь
Надеюсь, это поможет прояснить!;)