我理解LINQ中的延迟执行,如下所述: What are the benefits of a Deferred Execution in LINQ?
但是,延迟执行可能会导致错误,尤其是在多线程场景中,例如。对锁外的共享集合执行的评估。当一个返回延迟评估的方法嵌套了几个深层的方法层时,它会变得非常困难(至少对我而言)要记住或跟踪我是否适当锁定。
忽略无限序列(例如Fibonacci)等特殊情况并假设对集合进行过滤被认为是完整的(即,消费者不太可能进一步过滤结果),这将被视为“最佳方法” “当从方法返回IEnumerable的集合时 - 它是否已经被评估或推迟?
注意:“最佳方法”可以根据其他措施的效率/代码安全性进行定义,只需在您的回复中进行验证即可。我想知道社区如何做到这一点。
后续问题:如果结果被评估或推迟,在方法名称中明确说明是否有意义?
答案 0 :(得分:2)
您要编写的大部分代码都不是多线程的。事实上,当你想要急切地评估一个可枚举的时候,我只能想到三个原因:
在其他时候,您应该让它使用延迟执行。这会将评估推迟到实际需要的程度,并且可能会更快,具体取决于您应用的过滤器。例如,bigquery.First()
可能比bigquery.ToArray().First()
更快。你能确定用户已完成过滤吗?
此外,还有运行时will optimize certain LINQ queries。此示例取自Jon Skeet的文章LINQ To Objects and the performance of nested "Where" calls:
// 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>
。如果您希望结果是不可变的,请将其包装在ReadOnlyCollection<T>
中。