c# - 一些帮助理解 "yield"

标签 c# iterator yield

在我不断寻求减少吸取的过程中,我试图理解“ yield ”声明,但我一直遇到同样的错误。

The body of [someMethod] cannot be an iterator block because 'System.Collections.Generic.List< AClass>' is not an iterator interface type.

这是我卡住的代码:

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

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

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

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

最佳答案

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

IEnumerable<SomethingAppropriate>
IEnumerator<SomethingApropriate>

(感谢 JonMarc 指出 IEnumerator)

例子:

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

yield 是一个懒惰的数据生产者,仅在检索到第一个项目后才生产另一个项目,而返回一个列表将一次性返回所有内容。

所以是有区别的,需要正确声明方法。

有关详细信息,请阅读 Jon's answer here ,其中包含一些非常有用的链接。

关于c# - 一些帮助理解 "yield",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/317462/

相关文章:

c# - 单列的 EF Core 多重关系

c# - 如何从事件处理程序中删除自己?

C# 创建具有动态属性的对象 : LINQ select List<object> values by property names array

typescript - 为什么 TypeScript 的 IterableIterator<> 和 Generator<> 泛型略有不同?

c# - 在 C# 中生成返回查找列表或预加载静态列表更好吗?

c# - 不使用方法隐藏,为什么不调用父方法?

java - android xml解析中的hashmap

c++ - 减去和比较随机访问迭代器 : why and where?

c++ - 如果我们使用 notify_one() 来唤醒线程,我们还需要 yield() - 在 C++ 中吗?

ruby-on-rails - 使用多个 yield 插入内容