Search code examples
c#interfaceienumerableienumeratorexplicit-interface

Why does List<T> declare GetEnumerator() and IEnumerable<T>.GetEnumerator()?


Why does List define these three methods?

    public Enumerator GetEnumerator()
        => new Enumerator(this);

    IEnumerator<T> IEnumerable<T>.GetEnumerator()
        => new Enumerator(this);

    IEnumerator IEnumerable.GetEnumerator()
        => new Enumerator(this);

They are all doing the same thing. Wouldn't it be enough to just have this:

public Enumerator GetEnumerator()
        => new Enumerator(this);

Solution

  • Wouldn't it be enough to just have this:

    public Enumerator GetEnumerator()
           => new Enumerator(this);
    

    No, it wouldn't, because that wouldn't implement either IEnumerable<T> or IEnumerable, where the GetEnumerator() methods have return types of IEnumerator<T> and IEnumerator respectively.

    The return types have to match in order to implement the interface.

    Indeed, it's easy to test this for yourself:

    using System.Collections;
    using System.Collections.Generic;
    
    public class MyList<T> : IEnumerable<T>
    {
        public Enumerator GetEnumerator() =>
            new Enumerator();
    
        // Implement this fully so we can concentrate on IEnumerable<T>
        public struct Enumerator : IEnumerator<T>
        {
            public T Current => default;
            object IEnumerator.Current => default;
            public bool MoveNext() => true;
            public void Reset() {}
            public void Dispose() {}
        }
    }
    

    That gives errors of:

    • error CS0738: 'MyList<T>' does not implement interface member 'IEnumerable<T>.GetEnumerator()'. 'MyList<T>.GetEnumerator()' cannot implement 'IEnumerable<T>.GetEnumerator()' because it does not have the matching return type of 'IEnumerator<T>'.
    • error CS0738: 'MyList<T>' does not implement interface member 'IEnumerable.GetEnumerator()'. 'MyList<T>.GetEnumerator()' cannot implement 'IEnumerable.GetEnumerator()' because it does not have the matching return type of 'IEnumerator'.