【问题标题】:IEnumerable<int> Requires also the Non generic IEnumerator?IEnumerable<int> 还需要非泛型 IEnumerator?
【发布时间】:2011-11-27 14:36:08
【问题描述】:

3 个问题:

1) 为什么输出取自 NON 泛型函数?

2) 为什么我必须实现 ALSO 非泛型函数?

3) 如果我想查看通用函数输出(int 的)我需要做什么?

【问题讨论】:

    标签: c# .net generics ienumerable


    【解决方案1】:
    1. foreach 关键字根本不需要集合实现IEnumerable;相反,它将调用任何已定义的 GetEnumerator 方法。

    2. 出于兼容性原因,IEnumerable&lt;T&gt; 实现 IEnumerable

    3. 您应该显式实现IEnumerable.GetEnumerator(),并让普通方法返回IEnumerator&lt;T&gt;

    如果类有一个普通的GetEnumerator() 方法(与显式接口实现相反),编译器会调用它。
    规范说:

    • 否则,判断X类型是否有合适的GetEnumerator方法:
      • 在类型 X 上执行成员查找,带有标识符 GetEnumerator 并且没有类型参数。如果成员查找没有产生匹配, 或者它会产生歧义,或者产生不是方法的匹配 组,检查可枚举接口,如下所述。它是 建议在成员查找产生时发出警告 除了方法组或不匹配之外的任何内容。
      • 使用生成的方法组和空参数列表执行重载解析。如果重载决议导致没有 适用的方法,导致歧义,或导致单一 最好的方法,但该方法是静态的或非公开的,请检查 一个可枚举的接口,如下所述。建议一个 如果重载决议产生除 明确的公共实例方法或没有适用的方法。
      • [...]
    • 否则,请检查可枚举接口:

    【讨论】:

    【解决方案2】:

    1) 输出取自非泛型函数,因为它是隐式定义的(而泛型函数是显式定义的)。

    2) IEnumerable&lt;T&gt;继承自IEnumerable,所以任何继承自IEnumerable&lt;T&gt;的类型也必须实现IEnumerable的成员

    3) 将泛型定义隐式化,将非泛型定义显式化,例如

    public class Class1 : IEnumerable<int>
    {
        public IEnumerator<int> GetEnumerator()
        {
            yield return 1;
            yield return 2;
            yield return 3;
            yield return 4;
        }
    
        IEnumerator IEnumerable.GetEnumerator()
        {
            return this.GetEnumerator();
        }
    }
    

    请注意,您可以从非泛型方法返回泛型枚举数,因为IEnumerator&lt;T&gt; 继承自IEnumerator

    【讨论】:

      【解决方案3】:

      您需要同时实现这两个,因为IEnumerable&lt;T&gt; 派生自IEnumerable。要调用显式实现的方法,您需要强制转换为该接口。

      但通常你显式地实现非泛型方法和隐式地实现泛型方法。这样foreach 将使用通用方法。 foreach 对集合的类型使用 GetEnumerator() 方法,如果此方法不存在,则仅回退到接口方法。

      典型的实现是:

      public IEnumerator<int> GetEnumerator()
      {
         ...
      }
      
      System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
      {
        return GetEnumerator();//Forward to strongly typed version
      }
      

      【讨论】:

      • return GetEnumerator();//Fo 有错误:迭代器不能包含返回语句...
      • @RoyiNamir:摆脱yields。
      猜你喜欢
      • 1970-01-01
      • 2012-12-03
      • 2014-11-17
      • 1970-01-01
      • 1970-01-01
      • 2014-07-22
      • 2012-09-24
      • 2010-09-18
      • 1970-01-01
      相关资源
      最近更新 更多