接口实现和返回类型

Geo*_*ett 4 c# generics interface enumerator

List<T>类实现了IEnumerable<T>接口.它有一个GetEnumerator返回a 的方法List<T>.Enumerator.

我有一个如下所示的类,它给出了一个编译错误,指出返回类型GetEnumerator与接口不匹配.

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

'Entities.Helpers.InsertionSortedSet'未实现接口成员'System.Collections.Generic.IEnumerable.GetEnumerator()'.'Entities.Helpers.InsertionSortedSet.GetEnumerator()'无法实现'System.Collections.Generic.IEnumerable.GetEnumerator()',因为它没有匹配的返回类型'System.Collections.Generic.IEnumerator'.

鉴于它List<T>似乎返回它自己的Enumerator类(不是接口),但它确实实现了Enumeration<T>我很困惑的接口,因为我看不出我对那个类有什么不同.

我的设置有什么问题导致它失败,哪里List<T>有效?


我想返回一个InsertionSortedSet<T>.Enumerator而不是界面,因为它避免拳击,我需要切出.

Jam*_*are 7

它的抱怨,因为的GetEnumerator()返回IEnumerator<T>IEnumerable<T>接口.要满足,您的类型必须返回IEnumerator<T>(并且也是一个明确的类型IEnumerator).

但是,很多时候,类需要返回比接口指定的更具体的类型,但是接口不允许这样的协变返回类型.所以要做到这一点,你可以做什么List<T>做,并GetEnumerator()返回你的特定枚举器,但你必须实现为它返回一个显式实现,为此返回一个:IEnumerable.GetEnumerator()IEnumeratorIEnumerable<T>.GetEnumerator()IEnumerator<T>

    // This is your specific version, like List<T> does
    public Enumerator GetEnumerator()
    {
        return new Enumerator(this);
    }

    // This is the one with the return value IEnumerator<T> expects
    IEnumerator<T> IEnumerable<T>.GetEnumerator()
    {
        return new Enumerator(this);
    }

    // Plus, it also expects this as well to satisfy IEnumerable
    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
Run Code Online (Sandbox Code Playgroud)

如果你看,List<T>你会发现它实现GetEnumerator()了三次:

  • 一旦明确表示 IEnumerable<T>
  • 一旦明确表示 Enumerable
  • 一次具有特定于列表的返回

如果你愿意,你可以在你的班级做同样的事情(这就像你开始的那样)但如果你这样做,你必须明确地实施IEnumerable<T>.GetEnumerator()IEnumerable.GetEnumerator()

如果导航到定义,您可以通过选择它满足的不同接口(或通过将List<T>实例分配给IEnumerableIEnumerable<T>引用并转到定义)来查看对象浏览器中的其他定义:

对象资源管理器截图