使用LINQ时,&&和where where子句有什么区别?

Sci*_*-fi 16 .net c# linq

我是LINQ的新手,昨天发现你可以有多个where子句,例如:

var items = from object in objectList
where object.value1 < 100  
where object.value2 > 10  
select object;
Run Code Online (Sandbox Code Playgroud)

或者你可以写:

var items = from object in objectList
where object.value1 < 100  
   && object.value2 > 10  
select object;
Run Code Online (Sandbox Code Playgroud)

两者有什么区别?

Phi*_*ppe 19

第一个将被翻译成:

objectList.Where(o => o.value1 < 100).Where(o=> o.value2 > 10)
Run Code Online (Sandbox Code Playgroud)

而第二个将翻译成:

objectList.Where(o => o.value1 < 100 && o.value2 > 10)
Run Code Online (Sandbox Code Playgroud)

因此,在第一个中,您将有一个第一个过滤的序列再次过滤(第一个序列包含值<100的所有对象,第二个序列包含第一个序列中值> 10的所有对象),而第二个你将在同一个labda表达式中进行相同的比较.这对于Linq到对象是有效的,对于其他提供者,它取决于表达式的翻译方式.

  • 其实这是很不准确的。如果你检查 `Linq` 的源代码,你会看到 `Where` 有一个方法可以将 `.Where(x).Where(y)` 转换为 `.Where(x &amp;&amp; y)`。[来源](http://referencesource.microsoft.com/#System.Core/System/Linq/Enumerable.cs,f7e72dc9c9621f30) (3认同)

Tam*_*red 10

明确的答案让它有点不准确.

正如@Philippe所说,第一个将被翻译成:

objectList.Where(o => o.value1 < 100).Where(o=> o.value2 > 10)
Run Code Online (Sandbox Code Playgroud)

而第二个将翻译成:

objectList.Where(o => o.value1 < 100 && o.value2 > 10)
Run Code Online (Sandbox Code Playgroud)

Linq对链式Where通话有一点优化.

如果您检查Linq's源代码,您将看到以下内容:

class WhereEnumerableIterator<TSource> : Iterator<TSource>
{
    public override IEnumerable<TSource> Where(Func<TSource, bool> predicate)
    {
        return new WhereEnumerableIterator<TSource>(source, 
            CombinePredicates(this.predicate, predicate));
    }
}
Run Code Online (Sandbox Code Playgroud)

CombinePredicates将两个谓词组合在一起是什么&&:

static Func<TSource, bool> CombinePredicates<TSource>(Func<TSource, bool> predicate1,
    Func<TSource, bool> predicate2)
{
    return x => predicate1(x) && predicate2(x);
}
Run Code Online (Sandbox Code Playgroud)

所以objectList.Where(X).Where(Y)相当于objectList.Where(X && Y)除了查询的创建时间(无论如何都非常短)和两个谓词的调用.

底线是它不会过滤或迭代集合两次 - 而是一个复合时间.


Yan*_*rtz 6

第一个转换为:

objectList.Where(o => o.value1 < 100)
          .Where(o => o.value2 > 10);
Run Code Online (Sandbox Code Playgroud)

而后者得到你:

objectList.Where(o => o.value1 < 100 && o.value2 > 10);       
Run Code Online (Sandbox Code Playgroud)

它的功能完全相同,虽然第二个会省去方法调用,但性能上的差异可以忽略不计.使用对你来说更具可读性的东西.

也就是说,如果你正在使用linq来对象.如果您正在使用提供程序,则取决于它的实现方式(如果在结果查询中未考虑谓词,则结果可能是次优的).