Ответ 1
Итак, у нас есть несколько отдельных вопросов, которые здесь происходят.
Прежде всего, рассмотрим using
в блоке итератора. IEnumerator
продолжается IDisposable
. Код, который генерирует блоки итератора, на самом деле достаточно прост, что любые блоки try/finally (a using
приводит к созданию блока try/finally
) приводит к тому, что содержимое блока finally
вызывается в методе Dispose
перечислитель, если он еще не был вызван. До тех пор, пока вызывается перечислитель, он не пропустит StreamReader
.
Итак, теперь мы спрашиваем себя, находится ли перечислитель. Все операторы foreach
вызывают Dispose
в перечислителе (если он реализует IDisposable
). Они делают это, даже если вы выходите с помощью инструкции break
или return
, а также когда она заканчивается нормально.
Таким образом, вы можете быть уверены, что при любых обстоятельствах ресурс не будет просачиваться, запрещая случаи, когда ничто не может быть предотвращено от утечки (то есть кто-то, который отталкивает машину).