如何定义迭代器接口类型?

时间:2010-09-26 19:47:01

标签: c#

我写了一个实现IEnumerable<T>的类。我有一个返回MyClass的方法。如果我在该方法中尝试yield return,编译器会告诉我“...不能是迭代器块,因为......不是迭代器接口类型”。

那么,我该如何定义自己的接口迭代器类型?它是否必须是“抽象的”(不能定义任何方法)?

我想要做的是编写一堆可链接的方法,因此每个方法都应返回MyClass的实例。但我需要MyClass成为某种可枚举的。我没有使用某种基础数据类型,而是希望我能在任何地方yield return


@Oded:

class SharpQuery : IEnumerable<HtmlNode>
{
    public SharpQuery Find(string selector)
    {
        foreach (var n in this)
        {
            // filter the results
            yield return node;
        }
    }
}

3 个答案:

答案 0 :(得分:13)

不,那是不可能的。要了解为什么认为您有一个实现Zoo的类IEnumerable<Animal>,但也有很多其他成员。 ZooIEnumerable<Animal>但不一定相反 - 动物序列只是一系列动物。没有动物园饲养员,没有商店,没有入场费或任何使动物园成为动物园的东西。

当您使用yield return x时,返回类型不能是Zoo,因为您没有动物园 - 您只有一系列动物。

您可以做的是将其称为new Zoo(foo()),其中foo返回IEnumerable<Animal>,并将构造函数添加到接受Zoo的{​​{1}}。

答案 1 :(得分:2)

我认为当你使用yield return x时,你将生成一个IEnumerable的X类型。所以在你的情况下,它将是IEnumerable

从一个类继承并不会自动意味着它会隐式地将自己强制转换为该类型。所以,如果你写

class SharpQuery 
{
    public IEnumerable<HtmlNode> RepositoryItems { get; set; }
    public IEnumerable<HtmlNode> Find(string selector)
    {
        foreach (var n in this.RepositoryItems)
        {
            // filter the results
            yield return node;
        }
    }
}

它有效。 IEnumerable与SharpQuery不同。

答案 2 :(得分:2)

根据C#语言规范版本4.0的第8.2节:

  

包含一个或多个yield语句的块称为迭代器块。迭代器块用于将函数成员实现为迭代器。

第10.14节规定迭代器的返回类型必须是以下之一:

  • IEnumerator
  • IEnumerable
  • IEnumerator<T>
  • IEnumerable<T>

根据10.14.4节,调用迭代器不会立即执行迭代器块中的代码。而是创建并返回实现以下接口的枚举器对象:

  • IEnumerator
  • IEnumerator<T>
  • IDisposable

枚举器对象通常是编译器生成的具有私有可访问性的嵌套类的实例。