Я думал о методе IEnumerator.Reset()
. Я прочитал в документации MSDN, что это только для COM-взаимодействия. Как программист на С ++, мне кажется, что IEnumerator
, который поддерживает Reset
, - это то, что я бы назвал прямым итератором , тогда как IEnumerator
, который не поддерживает Reset
, на самом деле входной итератор .
Итак, первая часть моего вопроса: правильное ли это понимание?
Вторая часть моего вопроса: будет ли какая-то польза в C #, если будет проведено различие между входными итераторами и прямыми итераторами (или «перечислителями», если вы предпочитаете)? Разве это не поможет устранить некоторую путаницу между программистами, подобную той, которая содержится в этом ТАКом вопросе о клонировании итераторов ?
РЕДАКТИРОВАТЬ: Разъяснения для прямого и входного итераторов. Итератор ввода гарантирует, что вы можете перечислить элементы коллекции (или из функции генератора или входного потока) только один раз. Именно так работает 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
, другими словами, поддерживает многоходовые алгоритмы, то каждый раз, когда вы перебираете коллекцию, она будет отличаться. Это было бы нежелательно, потому что это было бы удивительным поведением. Этот пример немного фальшивый, но это происходит в реальном мире (например, чтение из файловых потоков).