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

时间:2015-06-25 21:59:41

标签: c# .net linq linq-to-objects .net-core

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

你可以在这一行看到例如迭代器https://github.com/dotnet/corefx/blob/master/src/System.Linq/src/System/Linq/Enumerable.cs#L168

的decalartion和实现

我假设如果他们经历了这样做的麻烦,而不是简单的屈服声明,那么必须有一些好处,但我不能立即看到哪一个,它看起来非常类似于我记得的几年前编译器会自动回读eric lippert的博客,我记得当我在早期重新实现LINQ和yield语句时,为了更好地理解它,性能配置文件类似于。 NET版本。

它引起了我的好奇心,但它也是一个非常重要的问题,因为我正处于一个相当大的数据中 - 在内存项目中,如果我错过了一些显而易见的东西,那就是这种方法我想知道更好的权衡。

编辑:澄清一下,我明白为什么他们不能在where方法中产生(不同容器类型的不同枚举),我不明白为什么他们实现迭代器本身(是,而不是分叉不同的迭代器,分叉不同的方法,根据类型不同地迭代,并屈服于自动实现状态机而不是手动情况1转到2案例2等。

1 个答案:

答案 0 :(得分:3)

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

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