如果 GetEnumerator() 的返回类型不同,IEnumerable.GetEnumerator() 的首选实现如何返回 GetEnumerator()?

问题描述

我试图理解为什么会出现这样的情况

 class Foo : IEnumerable<int>
    {
        public IEnumerator<int> GetEnumerator()
        {
            //....
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }
    }

不是编译器错误GetEnumerator() 返回 IEnumerator<int>IEnumerable.GetEnumerator() 应该返回 IEnumerator,但它返回通用版本 IEnumerator<int>,因为它只返回 GetEnumerator(); .很明显不同的返回类型。我在这里错过了什么?

解决方法

正如评论中所指出的,IEnumerator<T> 实现了 IEnumerator,因此本质上 IE<T> “是一个”IE。如果我们这样做可能更容易看到,这很好:

class Foo : IEnumerable<int>
{
    private IEnumerator<int> x;
    
    public IEnumerator<int> GetEnumerator()
    {
        return x;
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return x;
    }
}

如果我们把X的类型改成IEnumerator就不行了:

class Foo : IEnumerable<int>
{
    private IEnumerator x;
    
    public IEnumerator<int> GetEnumerator()
    {
        return x;
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return x;
    }
}

因为虽然 IE<T> is-a IE,但它并不意味着 IE is-a IE<T>,出于类似的原因,例如一个“字符串是一个对象”但不一定是一个“对象是一个字符串”

如果是这样:

class Lion:IAnimal{}

class Zoo{
  Lion GetLion() { }
  IAnimal GetAnimal() { return GetLion(); }
}

...你甚至不会质疑它:)