Linq.Where(x=>x==1) - 编译器在做什么

本文关键字:编译器 什么 Where Linq | 更新日期: 2023-09-27 17:57:20

我知道Linq是defferedexecution,但我想了解编译器如何处理这样的语句以及它如何在后台工作

我发现Linq很吸引人,但我担心我不明白引擎盖下发生了什么

Linq.Where(x=>x==1) - 编译器在做什么

Where() 是一个扩展方法,可以实现如下:

IEnumerable<T> Where(self IEnumerable<T> sequence, Func<T, bool> predicate) 
{
    foreach(T current in sequence)
        if( predicate(current) )
            yield return current;
}
x => x == 1

是一个匿名过程,如果 x == 1 则返回 true,否则返回 false,如下所示:

bool predicate(T value)
{
    return value == 1;
}

有关 Where() 中的迭代器块如何编译的详细信息,有一个很棒的系列解释了它们是如何编译的,从 Eric Lippert 的博客开始。

它将查询筛选为等于 1 的值。 考虑

IEnumerable<int> values = ...;
IEnumerable<int> filteredValues = values.Where(x => x == 1);

另一种编写方式如下

public static IEnumerable<int> ExampleWhere(IEnumerable<int> values) {
  foreach (var x in values) {
    if (x == 1) {
      yield return 1;
    }
  }
}

这有点取决于基础集合是什么。如果您谈论的是 LINQ to SQL、LINQ to Entities或一般的 LINQ,它可以产生巨大的不同。例如,如果这只是List上的语句,则它基本上是foreach枚举器的简写,其中在生成的枚举中仅返回与条件匹配的项目。

它正在这样做:

IQueryable<int> seq = ...;
return Queryable.Where(seq, Expression.Lambda(Expression.Equals(Expression.Constant(1), Expression.Parameter("x"))));

这只是稍微简化一下。

编辑:我应该限定我正在谈论的是seq是智商的情况。在这种情况下,指定的 linq 提供程序无关紧要。