3

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);
David Klempfner
  • 8,700
  • 20
  • 73
  • 153
  • 2
    https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/interfaces/explicit-interface-implementation – Tim Schmelter Jun 08 '21 at 08:07
  • 1
    `Enumerator GetEnumerator()` lets it return a struct enumerator for use in `foreach` loops, without allocating. `IEnumerator IEnumerable.GetEnumerator()` lets it implement the `IEnumerator GetEnumerator()` method from the `IEnumerable` interface, so you can do `IEnumerable x = new List(); foreach (var item in x) ...` – canton7 Jun 08 '21 at 08:10

1 Answers1

7

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'.
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194