使用类似的方法强制评估 LINQ 查询的公认做法是什么ToArray()
,是否有用于组成最佳查询链的一般启发式方法?我经常尝试一次完成所有事情,因为我注意到在这些情况下AsParallel()
在加速计算方面做得非常好。在查询执行没有副作用的计算但需要多次传递才能获取正确数据的情况下,是强制计算以ToArray()
正确的方式进行,还是以惰性形式保留查询更好?
3 回答
如果您不反对使用“实验”库,则可以使用Interactive Extensions库中的EnumerableEx.Memoize
扩展方法。
此方法提供了一个两全其美的选项,其中基础序列是按需计算的,但不会在随后的传递中重新计算。在我看来,另一个小好处是返回类型不是一个可变集合,就像使用ToArray
or一样ToList
。
让查询保持惰性形式,直到您开始多次评估查询,或者甚至更早,如果您需要以另一种形式使用它们,或者您面临闭包中捕获的变量更改其值的危险。
当查询包含您希望避免多次执行的复杂投影时,您可能需要进行评估(例如,为具有大量元素的序列构建复杂对象)。在这种情况下,评估一次并迭代多次会更明智。
如果要将结果返回或将它们传递给需要特定类型集合的另一个 API,则可能需要另一种形式的结果。
如果查询捕获的变量不在范围内,您可能希望或需要阻止访问修改后的闭包。在实际评估查询之前,您有其他代码“在您背后”更改其值的危险;当评估发生时,它将使用这些值而不是构造查询时存在的值。(但是,可以通过在另一个具有本地范围的变量中复制这些值来解决此问题)。
您通常只会ToArray()
在需要使用数组时使用,例如使用需要数组的 API。只要您不需要访问查询的结果,并且您不局限于某种连接上下文(例如 LINQ to SQL 或 LINQ to Entities 中的情况),那么您不妨只是使查询保持惰性形式。