c# - LINQ 与嵌套循环

标签 c# .net linq

我维护的代码有一个像下面这样的通用模式,一个带有 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 操作( SelectManyWhereSelect 等)都会产生一个新的占位符对象,表示待处理的 IEnumerable<T>。该操作的查询,然后当它最终被迭代时,每一个都会产生一个枚举器实例,以及上下文等。另外还有一个用于提升的 orderStorageId 的捕获变量上下文。等

请注意常规 foreach也会产生一个枚举器实例,但是 foreach优点是它还可以使用鸭子类型的枚举器——这意味着对于 List<T> 这样的东西它实际上使用的是 struct枚举器,不是 class枚举器。当然,直接(而不是在匿名方法中)使用局部变量 ( orderStorageId) 意味着不需要将其提升到状态/上下文对象中。

所以是的,原始 foreach更直接高效。有趣的问题是:差异重要。有时是,有时不是。

关于c# - LINQ 与嵌套循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18145493/

相关文章:

c# - 无法在我的 WPF 应用程序中使用 Array.Copy()

c# - 写c#for循环到页面

c# - 使用 C#/CSP 在 HSM 中使用不可导出 key 的 RSA 加密

c# - 为什么 .NET 将 UTC 日期更改为服务器时区?

c# - 使用Linq合并一个List中某个对象的方法返回的所有List

c# - 如何检查用户的输入是否存在于数据库表中?

c# - 从另一个表单访问字符串

.net - 如何在 .NET 中解压缩用 Lempel-Ziv Haruyasu 算法压缩的字节?

.net - 哪种类型的 key .NET 程序集用于签名以及如何创建它?

c# - linq where 包含列表中的所有项目