是否有可能确定一个IEnumerable< T>已执行递延挂起? [英] Is it possible to determine if an IEnumerable<T> has deffered execution pending?

查看:130
本文介绍了是否有可能确定一个IEnumerable< T>已执行递延挂起?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个接受可枚举函数。我需要确保普查员进行评估,但如果它是在一个列表或其他一些冻结集合中的所有准备我宁可不创建一个副本(例如,通过了ToList()或ToArray的())。冰冻我的意思是,其中一组项目已经建立了例如收藏清单阵列,FsharpSet,收藏等,而不是LINQ的东西,如选择()并在()。

I have a function that accepts an Enumerable. I need to ensure that the enumerator is evaluated, but I'd rather not create a copy of it (e.g. via ToList() or ToArray()) if it is all ready in a List or some other "frozen" collection. By Frozen I mean collections where the set of items is already established e.g. List, Array, FsharpSet, Collection etc, as opposed to linq stuff like Select() and where().

是否有可能创建一个函数ForceEvaluation,可以确定枚举已经递延执行挂起,然后评估枚举

Is it possible to create a function "ForceEvaluation" that can determine if the enumerable has deffered execution pending, and then evaluate the enumerable?

 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()}

 }

}

在一些调查研究,我意识到,这是几乎不可能在任何实际的意义,并需要复杂的代码检查每个迭代器。

After some more research I've realized that this is pretty much impossible in any practical sense, and would require complex code inspection of each iterator.

所以我要去与马克的回答的一个变种,并创建已知的安全类型的白名单,只是调用了ToList()什么也没在不是白名单上。

So I'm going to go with a variant of Mark's answer and create a white-list of known safe types and just call ToList() anything not on that is not on the white-list.

感谢大家的帮助。

编辑*
还送更多的思考之后,我意识到这是相当于停机问题。所以非常不可能的。

Edit* After even more reflection, I've realized that this is equivalent to the halting problem. So very impossible.

推荐答案

您的可能的尝试对 A希望检查的IList< ; T> 的ICollection< T> ,但要注意这些的可以的仍然是懒洋洋地实现 - 但它是非常罕见,和LINQ没有做到这一点 - 它只是使用迭代器(不懒惰集合)。所以:

You could try a hopeful check against IList<T> or ICollection<T>, but note that these can still be implemented lazily - but it is much rarer, and LINQ doesn't do that - it just uses iterators (not lazy collections). So:

var list = foos as IList<Foo>;
if(list != null) return list; // unchanged
return foos.ToList();

请注意,这是到正规的不同 .ToList(),它给你回一个不同的列表中的每个时间,保证无意外。

Note that this is different to the regular .ToList(), which gives you back a different list each time, to ensure nothing unexpected happens.

最具体的集合类型(包括 T [ ] 列表< T> )满足的IList< T> 。我不熟悉F#的集合 - 你需要检查

Most concrete collection types (including T[] and List<T>) satisfy IList<T>. I'm not familiar with the F# collections - you'd need to check that.

这篇关于是否有可能确定一个IEnumerable&LT; T&GT;已执行递延挂起?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆