La respuesta correcta es un poco inexacta.
Como dijo @Philippe, el primero que se traducirán a:
objectList.Where(o => o.value1 < 100).Where(o=> o.value2 > 10)
mientras que la segunda se traduce en:
objectList.Where(o => o.value1 < 100 && o.value2 > 10)
PeroLinq
tiene una poca optimización para llamadas encadenadas Where
.
Si inspecciona Linq's
código fuente se verá lo siguiente:
class WhereEnumerableIterator<TSource> : Iterator<TSource>
{
public override IEnumerable<TSource> Where(Func<TSource, bool> predicate)
{
return new WhereEnumerableIterator<TSource>(source,
CombinePredicates(this.predicate, predicate));
}
}
Lo CombinePredicates
no se está combinando los dos predicados con &&
entre ellos:
static Func<TSource, bool> CombinePredicates<TSource>(Func<TSource, bool> predicate1,
Func<TSource, bool> predicate2)
{
return x => predicate1(x) && predicate2(x);
}
Así objectList.Where(X).Where(Y)
es equivalente a objectList.Where(X && Y)
excepto por el tiempo de creación de la consulta (que de todos modos es extremadamente corto) y la invocación de dos predicados.
El fondo es que no lo hace filtro o iterar la colección dos veces - pero una vez compuesto.
En realidad eso es bastante inexacto. Si inspecciona las fuentes de 'Linq', verá que' Where' tiene un método que traduce '.Where (x) .Where (y)' en '.Where (x && y)'. [fuente] (http://referencesource.microsoft.com/#System.Core/System/Linq/Enumerable.cs,f7e72dc9c9621f30) –
Buen punto, no puedo decir si revisé esto en 2009 o si fue cierto todo el tiempo. – Philippe