The List<T> class implements the IEnumerable<T> interface. It has a method GetEnumerator that returns a List<T>.Enumerator.
I have a class as below, which gives a compile error saying the return type of GetEnumerator doesn’t match the interface.
public class InsertionSortedSet<T> : IEnumerable<T>
{
public struct Enumerator : IEnumerator<T>
{
// Required interface implemented
}
// Other interface methods implemented
public Enumerator GetEnumerator()
{
return new Enumerator(this);
}
}
‘Entities.Helpers.InsertionSortedSet’ does not implement interface member ‘System.Collections.Generic.IEnumerable.GetEnumerator()’. ‘Entities.Helpers.InsertionSortedSet.GetEnumerator()’ cannot implement ‘System.Collections.Generic.IEnumerable.GetEnumerator()’ because it does not have the matching return type of ‘System.Collections.Generic.IEnumerator’.
Given that List<T> seems to return it’s own Enumerator class (not the interface) and yet it does implement the Enumeration<T> interface I’m confused, as I can’t see what i’ve got different to that class.
What’s wrong with my setup that makes it fail, where List<T> works?
I want to return a InsertionSortedSet<T>.Enumerator rather than the interface as it avoids boxing, which I need to cut out.
It’s complaining because GetEnumerator() returns
IEnumerator<T>for theIEnumerable<T>interface. To satisfy, your type must returnIEnumerator<T>(and an explicit one forIEnumeratoras well).But, many times it’s desirable for a class to return a more specific type than the interface specifies, but interfaces don’t allow for covariant return types like that. So to do this, you can do what
List<T>does and haveGetEnumerator()return your specific enumerator, but you must also implement explicit implementations forIEnumerable.GetEnumerator()that returns anIEnumeratorand forIEnumerable<T>.GetEnumerator()that returns anIEnumerator<T>:If you look at
List<T>you’ll see that it implementsGetEnumerator()three times:IEnumerable<T>EnumerableYou could do the same in your class if you wish (which it sould like is the way you began) but if you do that you must explicitly implement
IEnumerable<T>.GetEnumerator()andIEnumerable.GetEnumerator()If you navigate to the definition, you can see the other definitions in the object browser by selecting the different interfaces it satisfies (or by assigning a
List<T>instance to anIEnumerableorIEnumerable<T>reference and going to definition):