Я заметил, что общий IEnumerator<T> наследует от IDisposable, но не общий интерфейс IEnumerator этого не делает. Почему он сконструирован таким образом?
Обычно мы используем оператор foreach для прохождения экземпляра IEnumerator<T>. Сгенерированный код foreach на самом деле имеет блок try-finally, который в конечном итоге вызывает Dispose().