【问题标题】:IEnumerable<T> provides two GetEnumerator methods - what is the difference between them?IEnumerable<T> 提供了两个 GetEnumerator 方法——它们之间有什么区别?
【发布时间】:2010-10-08 07:44:26
【问题描述】:

当我实现IEnumerable&lt;T&gt; 接口时,我看到两个GetEnumerator 方法:一个返回IEnumerator,另一个返回IEnumerator&lt;T&gt;。我什么时候会使用一个或另一个?

【问题讨论】:

    标签: ienumerable ienumerator


    【解决方案1】:

    之所以有两种方法是因为IEnumerable&lt;T&gt; 继承了IEnumerable 接口,所以您看到的是来自IEnumerable&lt;T&gt; 的泛型方法和来自IEnumerable 的非泛型方法。

    这是您希望在您的类型中实现接口的方式:

    class Foo : IEnumerable<Foo>
    {
        public IEnumerator<Foo> GetEnumerator()   
        {
            // do your thing here
        }
    
        // do a EIMI here and simply call the generic method
        IEnumerator IEnumerable.GetEnumerator()
        {
            this.GetEnumerator();
        }
    }
    

    【讨论】:

    • +1 - EIMI = 显式接口成员实现
    • 但是Foo : IEnumerable&lt;Foo&gt; 到底有什么意义呢?
    【解决方案2】:

    您通常同时实现两者。一个是更新的通用版本,它返回一个类型安全的枚举器 (IEnumerator&lt;T&gt;)。另一个是为了与旧代码兼容(返回IEnumerator)。一个典型的实现是:

    public IEnumerator<T> GetEnumerator() {
        foreach(T item in items) {
            yield return item;
        }
    }
    
    IEnumerator IEnumerable.GetEnumerator() {
        return GetEnumerator();
    }
    

    【讨论】:

    • 这个对我帮助很大,避免了嵌套枚举器的额外类!
    • +1。我也在谷歌上搜索找到一个避免嵌套枚举器类的参考实现,这是我得到的第一个答案。
    【解决方案3】:

    如果您正在实现IEnumerable&lt;T&gt; 泛型接口,您几乎总是必须使用泛型 GetEnumerator 方法 - 除非您将对象显式转换为(非泛型)IEnumerable。

    原因是向后兼容不支持泛型的 .NET 1.0/1.1。

    【讨论】:

      【解决方案4】:

      通常GetEnumerator() 调用GetEnumerator&lt;T&gt;(),所以行为上应该没有太大区别。至于为什么有两种方法,这样做是为了向后兼容以及在T 不是很感兴趣(或只是未知)的情况下使用。

      【讨论】:

        【解决方案5】:

        一个是通用的,另一个不是。我相信编译器更喜欢使用泛型重载。

        【讨论】:

          猜你喜欢
          • 2021-08-25
          • 2010-09-29
          • 1970-01-01
          • 2011-06-25
          • 1970-01-01
          • 1970-01-01
          • 2010-10-18
          • 2014-03-20
          • 1970-01-01
          相关资源
          最近更新 更多