我有一个接受Enumerable的函数.我需要确保枚举器被评估,但是我宁愿不创建它的副本(例如通过ToList()或ToArray()),如果它已经在列表或其他“冻结”集合中准备好了.通过Frozen我的意思是已经建立了一组项目的集合,例如List,Array,FsharpSet,Collection等,而不是像select()和where()这样的
linq东西.
是否可以创建一个函数“ForceEvaluation”,可以确定枚举是否已经执行挂起,然后评估枚举?
public void Process(IEnumerable<Foo> foos) { IEnumerable<Foo> evalutedFoos = ForceEvaluation(foos) EnterLockedMode(); // all the deferred processing needs to have been done before this line. foreach (Foo foo in foos) { Bar(foo); } } public IEnumerable ForceEvaluation(IEnumerable<Foo> foos) { if(??????) { return foos} else {return foos.ToList()} }
}
经过一些更多的研究,我意识到这在实际意义上几乎是不可能的,并且需要对每个迭代器进行复杂的代码检查.
所以我要跟Mark的答案一样,创建一个已知安全类型的白名单,然后调用ToList(),而不是在白名单上.
感谢大家的帮助.
编辑*
经过更多的反思,我意识到这相当于停止的问题.那么非常不可能
解决方法
您可以尝试对IList< T>或ICollection
var list = foos as IList<Foo>; if(list != null) return list; // unchanged return foos.ToList();
请注意,这与常规.ToList()不同,它每次返回一个不同的列表,以确保没有意外发生.
大多数具体的收集类型(包括T []和List< T>)满足IList T.我不熟悉F#系列 – 你需要检查.