C# LINQ vs嵌套循环

C# LINQ vs嵌套循环,c#,.net,linq,C#,.net,Linq,Im维护的代码有一个常见的模式,如下面所示,一个嵌套循环,使用if来查找某些元素 foreach (Storage storage in mStorage.Values) foreach (OrderStorage oStorage in storage.OrderStorage) if (oStorage.OrderStorageId == orderStorageId) 我想把它改成LINQ: fore

Im维护的代码有一个常见的模式,如下面所示,一个嵌套循环,使用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的嵌套循环的代码吗

实际上会创建更多的对象吗?或者C#编译器会发出类似于内部带有if的嵌套循环的代码吗

更多的对象;每个LINQ操作(
SelectMany
Where
Select
等)将生成一个新的占位符对象,该对象表示该操作的未决
IEnumerable
查询,然后在最后迭代时,每个操作都将生成一个枚举器实例,除了上下文等,还有一个捕获的变量上下文,用于提升的
orderStorageId

请注意,常规的
foreach
也将生成枚举器实例,但
foreach
的优点是它也可以使用duck类型的枚举器,这意味着对于
List
之类的事情,它实际上使用的是
struct
枚举器,而不是
class
枚举器。当然,直接(而不是匿名方法)使用局部变量(
orderStorageId
)意味着不需要将其提升到状态/上下文对象中


因此,是的,原始
foreach
更直接、更高效。有趣的问题是:差异重要吗。有时是,有时不是。

同意@MarcGravel的观点,LINQ的性能受到了影响,但它允许潜在的可维护性增加和潜在的更容易的并行性。性能与可维护性的两难选择使计算机编程成为一门艺术。