【发布时间】:2012-09-14 15:01:49
【问题描述】:
如果items 是 LINQ 表达式的结果:
var items = from item in ItemsSource.RetrieveItems()
where ...
假设每个项目的生成需要一些不可忽略的时间。
有两种可能的操作模式:
-
使用
foreach将允许在集合开始时比最终可用的项目更早地开始处理项目。但是,如果我们想稍后再次处理同一个集合,我们将不得不复制保存它:var storedItems = new List<Item>(); foreach(var item in items) { Process(item); storedItems.Add(item); } // Later foreach(var item in storedItems) { ProcessMore(item); }因为如果我们刚刚创建了
foreach(... in items),那么ItemsSource.RetrieveItems()会再次被调用。 -
我们可以直接使用
.ToList(),但这会迫使我们等待最后一个项目被检索,然后才能开始处理第一个项目。
问题:是否有 IEnumerable 实现会像常规 LINQ 查询结果一样第一次迭代,但会在处理过程中实现,以便第二次 foreach 会迭代存储的值?
【问题讨论】:
-
编写一个接收原始 IEnumerable 的 CachingEnumerable/CachingEnumerator 实现有多难,并且枚举器将循环遍历缓存,然后从原始缓存中提取其他值直到完成,并在完成时缓存它?但是不,我不知道有任何框架实现可以做到这一点。
-
@Rich:应该不会太难,就是想看看有没有。
-
嗯,问题是
foreach实际上与它自己的IEnumerator一起工作,而IEnumerator有它自己的状态。当然,您可以将IQueryable或IEnumerable包装在缓存中;但是,您必须处理两个IEnumerators 以不同速率同时枚举的可能性。 -
这是典型的情况,我会停止使用 LINQ 来支持标准循环 :) 无论如何,挑战非常有趣。
-
Caching IEnumerable的可能重复
标签: c# .net linq ienumerable