是否可以克隆IEnumerable <T>实例,保存迭代状态的副本?

Ste*_*idi 10 .net c# linq ienumerable clone

我想创建一个副本,IEnumerator<T>以便我可以从集合中的特定位置重新启动枚举过程.显然,对于实现的集合,这样做没有任何好处IList,因为我们可以记住感兴趣的索引.

使用yield语句和Linq函数的组合是否有一种聪明的方法来完成此任务?我找不到合适的Clone()方法来复制枚举器,并且希望避免使用Enumerable.Skip()将新的枚举器重新定位到所需的恢复点.

此外,我希望尽可能保持解决方案的通用性,而不必依赖任何具体集合中的状态.

Mar*_*ell 5

你能做的最好的事情是写一些东西来保留一个缓冲区(可能是一个Queue<T>)从一个而不是另一个消耗的数据(如果你将一个迭代器推进 100 万个位置,这会变得混乱/昂贵,但不理会另一个)。不过,我真的认为你最好重新考虑设计,然后只使用GetEnumerator()(即另一个foreach)重新开始 - 或者在列表/数组/任何东西中缓冲数据(如果很短)。

没有什么优雅的内置。


更新:也许这里一个有趣的替代设计是“ PushLINQ ”;而不是克隆迭代器,它允许多个“事物”到消耗相同的数据馈送的同时

在这个例子中(摘自 Jon 的页面),我们并行计算多个聚合:

// Create the data source to watch
DataProducer<Voter> voters = new DataProducer<Voter>();

// Add the aggregators
IFuture<int> total = voters.Count();
IFuture<int> adults = voters.Count(voter => voter.Age >= 18);
IFuture<int> children = voters.Where(voter => voter.Age < 18).Count();
IFuture<int> youngest = voters.Min(voter => voter.Age);
IFuture<int> oldest = voters.Select(voter => voter.Age).Max();

// Push all the data through
voters.ProduceAndEnd(Voter.AllVoters());

// Write out the results
Console.WriteLine("Total voters: {0}", total.Value);
Console.WriteLine("Adult voters: {0}", adults.Value);
Console.WriteLine("Child voters: {0}", children.Value);
Console.WriteLine("Youngest vote age: {0}", youngest.Value);
Console.WriteLine("Oldest voter age: {0}", oldest.Value);
Run Code Online (Sandbox Code Playgroud)

  • 噗!睡眠是给弱者的!接下来你会建议午休吗?疯狂我告诉你,疯狂! (7认同)
  • 不,他会在 Jon Skeet 睡着时覆盖他的帐户。Jon skeet 不睡觉,所以他(Skeet)在他应该睡着的时候覆盖 Marc 的帐户。;) (2认同)