我维护的代码有一个像下面这样的通用模式,一个带有 if 的嵌套循环来查找某些元素。
foreach (Storage storage in mStorage.Values)
foreach (OrderStorage oStorage in storage.OrderStorage)
if (oStorage.OrderStorageId == orderStorageId)
我想把它改成 LINQ:
foreach (OrderStorage oStorage in (from storage in mStorage.Values
from oStorage in storage.OrderStorage
where oStorage.OrderStorageId == orderStorageId
select oStorage))
但这似乎并不那么吸引人,因为这里发生的事情不太透明,可能会创建更多对象,从而在内存和 CPU 方面降低性能。实际上是否会创建更多对象,或者 C# 编译器是否发出类似于内部带有 if 的嵌套循环的代码?
最佳答案
Will there actually be more objects created or does the C# compiler emit code resembling the nested loop with an if inside?
更多对象;每个 LINQ 操作( SelectMany
、 Where
、 Select
等)都会产生一个新的占位符对象,表示待处理的 IEnumerable<T>
。该操作的查询,然后当它最终被迭代时,每一个都会产生一个枚举器实例,以及上下文等。另外还有一个用于提升的 orderStorageId
的捕获变量上下文。等
请注意常规 foreach
也会产生一个枚举器实例,但是 foreach
优点是它还可以使用鸭子类型的枚举器——这意味着对于 List<T>
这样的东西它实际上使用的是 struct
枚举器,不是 class
枚举器。当然,直接(而不是在匿名方法中)使用局部变量 ( orderStorageId
) 意味着不需要将其提升到状态/上下文对象中。
所以是的,原始 foreach
更直接高效。有趣的问题是:差异重要。有时是,有时不是。
关于c# - LINQ 与嵌套循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18145493/