Это синтаксический сахар.Тем не менее, обратите внимание, что foreach работает, вызывая GetEnumerator (), затем MoveNext () до тех пор, пока не будет возвращен другой элемент, а затем всегда вызывает Dispose () для перечисленного ранее перечислителя.Если вы хотите сделать то же самое, не забывайте, что Dispose ()!
Кроме того, CLR выполняет некоторые приемы, связанные с получением перечислителя.См. здесь и здесь , например.