为什么linq-to对象手动实现迭代器

本文关键字:实现 迭代器 linq-to 对象 为什么 | 更新日期: 2023-09-27 17:59:52

在浏览.net核心源代码时,我注意到即使是源代码形式的迭代器类也是手动实现的,而不是依赖于yield语句和自动IEnumerable实现。

例如,您可以在这一行中看到where迭代器的decartition和实现https://github.com/dotnet/corefx/blob/master/src/System.Linq/src/System/Linq/Enumerable.cs#L168

我假设,如果他们经历了这样做的麻烦,而不是简单的收益率声明,肯定会有一些好处,但我不能立即看出是哪一个,这似乎与我几年前回读ericlippert的博客时所记得的编译器自动执行的操作非常相似,我还记得在LINQ早期,为了更好地理解它,我天真地用yield语句重新实现了它,当时的性能配置文件与.NET版本类似。

这激发了我的好奇心,但这也是一个非常重要的问题,因为我正在进行一个相当大的内存数据项目,如果我错过了一些明显的东西,使这种方法变得更好,我很想知道权衡。

编辑:为了澄清,我确实理解为什么他们不能只在where方法中屈服(不同容器类型的不同枚举),我不明白的是,他们为什么实现迭代器本身(也就是说,不是分叉到不同的迭代器,而是分叉到不同方法,根据类型进行不同的迭代,并屈服于拥有自动实现的状态机,而不是手动情况1转到2情况2等等)。

为什么linq-to对象手动实现迭代器

一个可能的原因是专用迭代器执行一些优化,比如组合选择器和谓词以及利用索引集合。

这些方法的有用之处在于,与yield的编译器魔力相比,一些源可以以更优化的方式迭代。通过创建这些自定义迭代器,它们可以将有关源的额外信息传递给单链中的后续LINQ操作(而不是使该信息仅对链中的第一个操作可用)。因此,所有WhereSelect操作(它们之间没有任何其他操作)都可以作为一个操作来执行。