Я думал о методе IEnumerator.Reset()
. Я читал в документации MSDN, что это только для COM-взаимодействия. Как программист на C++, мне кажется, что IEnumerator
, поддерживающий Reset
, я бы назвал прямой итератор, тогда как IEnumerator
, который не поддерживает Reset
, на самом деле является итератором ввода а>.
Итак, первая часть моего вопроса: правильно ли это понимание?
Вторая часть моего вопроса: было бы полезно в C#, если бы проводилось различие между итераторами ввода и итераторами вперед (или «перечислителями», если хотите)? Не поможет ли это устранить некоторую путаницу среди программистов, подобную той, что найдена в этом SO вопрос о клонировании итераторов< /а>?
РЕДАКТИРОВАТЬ: уточнение по итераторам вперед и ввода. Итератор ввода гарантирует, что вы можете перечислить элементы коллекции (или из функции-генератора, или из входного потока) только один раз. Именно так работает IEnumerator в C#. Возможность повторного перечисления определяется тем, поддерживается ли Reset
. Прямой итератор не имеет этого ограничения. Вы можете перечислять членов так часто, как хотите.
Некоторые программисты на C# не понимают, почему нельзя надежно использовать IEnumerator
в многопроходном алгоритме. Рассмотрим следующий случай:
void PrintContents(IEnumerator<int> xs)
{
while (iter.MoveNext())
Console.WriteLine(iter.Current);
iter.Reset();
while (iter.MoveNext())
Console.WriteLine(iter.Current);
}
Если мы вызовем PrintContents
в этом контексте, нет проблем:
List<int> ys = new List<int>() { 1, 2, 3 }
PrintContents(ys.GetEnumerator());
Однако посмотрите на следующее:
IEnumerable<int> GenerateInts() {
System.Random rnd = new System.Random();
for (int i=0; i < 10; ++i)
yield return Rnd.Next();
}
PrintContents(GenerateInts());
Если бы IEnumerator
поддерживал Reset
, другими словами, поддерживал многопроходные алгоритмы, то каждый раз, когда вы перебирали коллекцию, она была бы другой. Это было бы нежелательно, потому что это было бы удивительным поведением. Этот пример немного фальшивый, но он действительно встречается в реальном мире (например, чтение из файловых потоков).
IEnumerator.Reset
, а неIEnumerable<T>.Reset
, верно? - person Doug McClean   schedule 28.10.2009