I am trying to understand why something like
class Foo : IEnumerable<int>
{
public IEnumerator<int> GetEnumerator()
{
//....
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
isn't a compiler error. GetEnumerator()
returns IEnumerator<int>
while IEnumerable.GetEnumerator()
is supposed to return IEnumerator
, yet it return the generic version which is IEnumerator<int>
, as it just returns GetEnumerator();
. So clearly different return types. What am I missing here?
As is pointed out in the comments, an IEnumerator<T>
implements IEnumerator
so in essence an IE<T>
"is a" IE
. It's probably easier to see if we do this, which is fine:
class Foo : IEnumerable<int>
{
private IEnumerator<int> x;
public IEnumerator<int> GetEnumerator()
{
return x;
}
IEnumerator IEnumerable.GetEnumerator()
{
return x;
}
}
It doesn't work if we change the type of X to IEnumerator:
class Foo : IEnumerable<int>
{
private IEnumerator x;
public IEnumerator<int> GetEnumerator()
{
return x;
}
IEnumerator IEnumerable.GetEnumerator()
{
return x;
}
}
Because while an IE<T>
is-a IE
, it doesn't mean an IE
is-a IE<T>
, for similar reasons that e.g. a "string is-a object" but not necessarily a "object is-a string"
Had it been this:
class Lion:IAnimal{}
class Zoo{
Lion GetLion() { }
IAnimal GetAnimal() { return GetLion(); }
}
..you wouldn't even have questioned it :)