如何将现有的Reset(),MoveNext()和Current捆绑到C#中基于收益的迭代器中?

时间:2018-08-07 07:51:56

标签: c# iterator yield-return

我有一个简单的类MyClass,它已经具有Reset(),MoveNext()和Current片段。但是它不提供迭代器,只是公开那些组件。

我从这里开始:

public IEnumerator<MyClass> GetEnumerator()
{
    Reset();
    while (MoveNext())
        yield return Current;
}

哪个会触发以下错误:

CS1579 foreach语句不能对'IEnumerator'类型的变量进行操作,因为'IEnumerator'不包含'GetEnumerator'的公共实例定义

我尝试了很多其他方法,但是没有乐趣。

有人会指出我正确的方向吗?

谢谢!

2 个答案:

答案 0 :(得分:2)

我猜你的代码做了类似的事情

foreach(var variable in collection.GetEnumerator())
{
 //do some stuff
}

您可以省略GetEnumerator调用。如果您实现IEnumerable的类,它将被自动调用。

就这样:

foreach(var variable in collection)
{
//do some stuff
}

答案 1 :(得分:0)

要点:

  • 您应该在集合上调用foreach,而不是在枚举器上调用
  • 集合本身不需要实现MoveNextCurrent,枚举器则需要实现
  • 使用GetEnumerator()语句实现IEnumerator<T>之类的yield时,MoveNextCurrent是自动实现的,参数类型T不应正好MyClass

Documentation on CS1579

  

要使用foreach语句遍历集合,请   集合必须满足以下要求:

     
      
  • 其类型必须包含一个公共的无参数GetEnumerator方法,其返回类型可以是类,结构或接口类型。
  •   
  • GetEnumerator方法的返回类型必须包含一个名为Current的公共属性和一个名为的无参数公共方法   MoveNext,其返回类型为布尔值。
  •   

这是从1到5的简单数字集合的示例:

class MyCollection
{
    public IEnumerator<int> GetEnumerator()
    {
        for (int index = 1; index <= 5; index++) { 
            yield return index;
        }
    }
}

现在您可以使用foreach遍历它:

var collection = new MyCollection();
foreach(var element in collection) {
    Console.Write(element);
}