CLR如何解释以下LINQ查询

use*_*051 3 c# linq

我有2个obj1和的列表obj2

var list1 = new List<obj1>();
var list2 = new List<obj2>();
Run Code Online (Sandbox Code Playgroud)

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

var filteredlist = list1.Where(o => list2.Select(o2 => o2.name)
                                         .Distinct()
                                         .Contains(o.name));
Run Code Online (Sandbox Code Playgroud)

以上Linq查询等于以下?

 var distinctNames = list2.Select(o2 => o2.name).Distinct();
 var filteredlist = list1.Where(o => distinctNames.Contains(o.name));
Run Code Online (Sandbox Code Playgroud)

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

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

Mat*_*ten 8

LINQ只是IEnumerable接口上定义的一组扩展方法,因此它不是"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;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,选择查询将是类似的

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

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

所以你的问题的答案是"是的,它们或多或少相当",但它涉及很多lambdas :)并且"是的,它将重做Distinct每次迭代",因为它再次调用生成的lambda.您最好innerAction通过ToArray()ToList()(在您的情况下,在where条件的内部操作上调用它)强制评估我的第一个列表.