3

我理解 LINQ 中的延迟执行,如下所述:LINQ 中的延迟执行有什么好处?

但是,延迟执行可能会导致错误,尤其是在多线程场景中,例如。对锁外的共享集合执行的评估。当返回延迟评估的方法嵌套在几个方法层深处时,它会变得很难(至少对我而言)记住或跟踪以便我适当地锁定。

省略无限序列(例如斐波那契)等特殊情况,并假设集合的过滤被认为是完整的(即消费者不太可能进一步过滤结果),返回时将被认为是“最佳方法”来自方法的 IEnumerable 集合——它应该已经被评估还是推迟?

注意:“最佳方法”可以根据其他一些措施的效率/代码安全性来定义,只需在您的回复中进行验证。我想知道社区是如何做到的。

后续问题:如果结果被评估或延迟,在方法名称中显式声明是否有意义?

4

1 回答 1

2

您将编写的大部分代码都不是多线程的。事实上,当你想要急切地评估一个可枚举时,我能想到的只有三个原因:

  1. 您需要在多线程环境中使用它。您应该改为将其设为列表或数组。
  2. 您希望随机访问可枚举。您应该改为将其设为列表或数组。
  3. 您想控制评估何时发生(例如,如果它很昂贵)。

在其他时候,您应该让它使用延迟执行。这会将评估推迟到实际需要的时间点,并且可能会更快,具体取决于您应用的过滤器。例如,bigquery.First()可能比bigquery.ToArray().First(). 您能否确定用户已完成过滤?

此外,运行时将优化某些 LINQ 查询。此示例取自Jon Skeet的文章LINQ To Objects 和嵌套“Where”调用的性能

// Normal LINQ query
var query = list.Where(x => Condition1(x))
                .Where(x => Condition2(x))
                .Select(x => Projection1(x))
                .Select(y => Projection2(y));

// After optimization
var query = list.WhereSelect(x => Condition1(x) && Condition2(x),
                             x => Projection2(Projection1(x)); 

顺便说一句,您的方法应该返回他们可以返回的最具体的可见类型。例如,在内部处理T[]数组或List<T>列表的方法通常不应只返回一个IEnumerable<T>. 如果您希望结果是不可变的,请将其包装在 a 中ReadOnlyCollection<T>

于 2013-03-20T16:22:09.053 回答