Search code examples
c#linqenumerator

Linq list of enumerators seem to be recreated when accessed through linq


I am trying to understand what goes wrong in the following piece of code.

    var signals = new List<List<double>>
    {
        new List<double> {1, 2, 3},
        new List<double> {2, 3, 4},
    };

    var enumerators = signals.Select(l => l.GetEnumerator()).ToList();

    if (enumerators.All(enumerator => enumerator.MoveNext()))
    {
        var cummulative = enumerators.Sum(enumerator => enumerator.Current);
    }

Why are both enumerators pointing to the current value 0? I would expect both would point to the first number in the list, which would be 1 and 2 respectively.

Each time I access the enumerator via linq it seems to restart. Why?


Solution

  • Change your code as per below

    var enumerators = signals.Select(l => l.GetEnumerator() as IEnumerator<double>).ToList();
    

    As per this SO post

    It is because the enumerator of List is a struct whereas the enumerator of Array is a class.

    So when you call Enumerable.All with the struct, copy of enumerator is made and passed as a parameter to Func since structs are copied by value. So e.MoveNext is called on the copy, not the original.