Ответ 1
Это не то, как я прочитал С# spec [Word doc]. Раздел 10.14.4 "Объекты перечислителя":
... [E] объекты числителя не поддерживают метод IEnumerator.Reset. Вызов этого метода вызывает исключение System.NotSupportedException.
Однако этот раздел (и оператор) специфичен для "объектов перечислителя", который определяется как:
Когда член функции, возвращающий тип интерфейса перечислителя, реализуется с использованием блока итератора, вызов элемента функции не сразу выполняет код в блоке итератора. Вместо этого создается и возвращается объект перечисления .
Другими словами, "объект перечислителя" является компилятором, сгенерированным IEnumerator
1. Нет ограничений для каждого IEnumerator
, только те, которые генерируются из блоков итератора (aka yield
).
Почему? Я подозреваю, потому что это невозможно сделать в общем случае - без сохранения каждой ценности и связанных с этим ограничений памяти. Объедините это с тем, что IEnumerator.Reset()
редко используется (когда последний раз, когда вы Reset перечислитель?) И что MSDN специально призывает, что ему нужно не будут реализованы:
Метод Reset предоставляется для совместимости COM. Это необязательно должно быть реализовано; вместо этого разработчик может просто выбросить исключение NotSupportedException.
и вы можете вырезать много сложностей, и никто не замечает этого.
Как и требовать, чтобы он выбрал 2 я предполагаю, что это просто проще, чем позволить разработчику решить. IMO, это немного требует запроса - могут быть разумные случаи, когда компилятор (или другая реализация 1) может генерировать метод Reset, но я не вижу его как реальная проблема.
1 Технически спецификация оставляет возможность других реализаций:
Объект перечислителя обычно является экземпляром класса перечислителя, сгенерированного компилятором, который инкапсулирует код в блок итератора и реализует интерфейсы перечислителя, но возможны другие методы реализации.
но я не знаю других конкретных реализаций. Независимо от того, чтобы быть совместимым, другим реализациям "объекта-перечислителя" пришлось бы также метать NotSupportedException
.
2 Nitpicker corner: Я думаю, что может быть какое-то придирчиво даже в "требовании" бросить. Спектр, не используя предпочтительный "ДОЛЖЕН, ДОЛЖЕН, МОЖЕТ" формулировать, оставляет его немного открытым. Я читаю "причины" больше как примечание о реализации - не требование. Опять же, я не читал всю спецификацию, поэтому, возможно, они определяют эти термины немного больше или более явны в другом месте.