c# - CLR 如何解释以下 LINQ 查询

标签 c# linq

我有 2 个 obj1obj2 列表

var list1 = new List<obj1>();
var list2 = new List<obj2>();

obj1 和 obj2 共享一个名为 name 的字符串属性,我需要通过 list2 中可用的 name 属性值过滤 list1,所以我做了以下操作

var filteredlist = list1.Where(o => list2.Select(o2 => o2.name)
                                         .Distinct()
                                         .Contains(o.name));

上面的 Linq 查询是否等同于下面的查询?

 var distinctNames = list2.Select(o2 => o2.name).Distinct();
 var filteredlist = list1.Where(o => distinctNames.Contains(o.name));

我的问题是在第一个查询中,clr 是否会创建一个临时变量来保存 distinctNames,即使我没有像在第二个查询中那样自己创建它?或者它会在每次迭代时重做 Select Distinct from list2 吗?

如果它不创建临时变量,您将如何在一行中编写此查询?

最佳答案

LINQ只是定义在IEnumerable接口(interface)上的一组扩展方法,因此不是“CLR如何做到这一点”的问题。您的 LINQ 查询等同于

Func<bool> innerAction = list2.Select(o2 => o2.name).Distinct().Contains(o => o.name);
foreach(var e1 in list1)
{
    bool condition = innerAction();
    if (condition)
    {
        yield return e1;
    }
}

然后选择查询将类似于

Func<TIn, TOut> selectFunction = e => e.name;
foreach(var e2 in list2)
{
    yield return selectFunction(e2);
}

结果将传递给 distinct 函数,这是另一个 foreach 循环,然后传递给 contains 函数,这将导致另一个 foreach 循环。

所以你的问题的答案是“是的,它们或多或少是等价的”,但它涉及很多 lambdas :) 并且“是的,它会在每次迭代时重做 Distinct” ,因为它再次调用生成的 lambda。您最好通过 ToArray()ToList()(在您的情况下,将其称为关于 where 条件的内部操作)。

关于c# - CLR 如何解释以下 LINQ 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20989791/

相关文章:

c# - 有没有一种简单的方法可以验证数据库模式是否正是我期望它使用 Entity Framework 的方式?

.net - 多个表的 DRY LINQ 谓词过滤器

c# - 基于谓词拆分 LINQ 查询

c# - 如何|封闭变量存储在哪里?

c# - 将嵌套的 foreach 编写为 LINQ 以聚合两个单独的值

c# - 如何解释 C# 中的伪代码?

c# - 从范围内看不到标签匹配 'AutofacWebRequest' 的范围

c# - JSON序列化属性名称以特殊字符开头的匿名对象

c# - Winform 应用程序第一个 Web 请求很慢

c#、Linq、选择和计数