我有 2 个 obj1
和 obj2
列表
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/