有些有助于理解“收益”

在我永恒的追求吮吸少我试图理解“收益”的声明,但我不断遇到同样的错误。

[someMethod]的主体不能是迭代器块,因为'System.Collections.Generic.List <AClass>'不是迭代器接口类型。

这是我卡住的代码:

foreach (XElement header in headersXml.Root.Elements()){
    yield return (ParseHeader(header));                
}

我究竟做错了什么? 我不能在迭代器中使用yield吗? 那有什么意义? 在这个例子中,它表示List<ProductMixHeader>不是迭代器接口类型。 ProductMixHeader是一个自定义类,但我想象List是一个迭代器接口类型,不是吗?

- 编辑 -
感谢所有快速回答。
我知道这个问题并不是全新的,同样的资源不断涌现。
事实证明,我想我可以返回List<AClass>作为返回类型,但由于List<T>不是懒惰,它不能。 将我的返回类型更改为IEnumerable<T>解决了问题:D

一个有点相关的问题(不值得打开一个新线程):如果我确定99%的情况下我会去.ToList(),值得给IEnumerable<T>作为返回类型吗? 性能影响会是什么?


使用yield return的方法必须声明为返回以下两个接口之一:

IEnumerable<SomethingAppropriate>
IEnumerator<SomethingApropriate>

(感谢Jon和Marc指出IEnumerator)

例:

public IEnumerable<AClass> YourMethod()
{
    foreach (XElement header in headersXml.Root.Elements())
    {
        yield return (ParseHeader(header));                
    }
}

yield是一个懒惰的数据生成器,只有在第一个被检索后才生成另一个项目,而返回一个列表将一次返回所有内容。

所以有一个区别,你需要正确地声明该方法。

欲了解更多信息,请阅读乔恩的答案,其中包含一些非常有用的链接。


这是一个棘手的话题。 简而言之,这是一种实现IEnumerable及其朋友的简单方法。 编译器为您构建一个状态机,将参数和局部变量转换为新类中的实例变量。 复杂的东西。

我有这方面的一些资源:

  • 深入了解C#的第6章(从该页面免费下载)
  • 迭代器,迭代器块和数据管道(文章)
  • 迭代器块实现细节(文章)

  • “yield”创建一个迭代器块 - 一个编译器生成的类,可以实现IEnumerable[<T>]IEnumerator[<T>] 。 Jon Skeet在C#深度的第6章中对此进行了很好的(而且是免费的)讨论。

    但基本上 - 要使用“yield”,您的方法必须返回IEnumerable[<T>]IEnumerator[<T>] 。 在这种情况下:

    public IEnumerable<AClass> SomeMethod() {
        // ...
        foreach (XElement header in headersXml.Root.Elements()){
            yield return (ParseHeader(header));                
        }
    }
    
    链接地址: http://www.djcxy.com/p/9109.html

    上一篇: Some help understanding "yield"

    下一篇: Can someone demystify the yield keyword?