2011-01-26 4 views

Respuesta

2

Habrá un solo bucle para los tres comandos.

Si desea más información, recomiendo Jon Skeet's blog, donde describe una reimplementación de LINQ to Objects.

+0

¿Hay consultas más complejas, cuando habrá más bucles? –

+2

Puedes crear algunos. Hay comandos que requieren ejecutar la colección completa como OrderBy(), por ejemplo. – StampedeXV

+0

@Mary, sí, algunos operadores requieren mirar todos los elementos antes de continuar, como GroupBy. Si tuviera que combinar varios GroupBy, se producirían múltiples interacciones a través de los datos (aunque la siguiente iteración sería sobre los grupos en lugar de cada entrada individual). También habrá una sobrecarga más alta si hay una subconsulta, como list.where (x => list.count (x)> 2) ;. La subconsulta causará un bucle separado para cada elemento de la lista. –

8

Sum consumirá la salida del filtro Where, que consumirá la salida de la proyección Select, que consumirá el collection. Sum recorrerá la secuencia filtrada una vez, que recorrerá la proyección una vez, que recorrerá el collection una vez. Por lo tanto, la colección se repetirá exactamente una vez.

Aquí hay un experimento lindo que usted puede hacer para ver esto:

class Sequence : IEnumerable<int> { 
    public IEnumerator<int> GetEnumerator() { 
     for (int i = 0; i < 17; i++) { 
      Console.WriteLine(i); 
      yield return i; 
     } 
    } 

    IEnumerator IEnumerable.GetEnumerator() { 
     return GetEnumerator(); 
    } 
} 

continuación:

Sequence sequence = new Sequence(); 
int sum = sequence.Select(x => 2 * x).Where(x => x % 4 == 0).Sum(); 
Console.WriteLine("Sum is {0}", sum); 

la salida será:

0 
1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
Sum is 144 

mostrando que sequence se repite exactamente una vez .

+1

Saludo el esfuerzo del código de muestra. Sin embargo, mostrar que una instancia de Secuencia solo se enumera una vez no es suficiente para demostrar que el resultado de Seleccionar y el resultado de Donde no se enumeran por separado. –

+0

@David B: Por supuesto que no, pero debería darle al OP una idea de lo que está sucediendo. La única forma de demostrar completamente que la secuencia solo se enumera una vez es comprender la implementación de LINQ. Especifiqué en el párrafo inicial de mi respuesta por qué debería ocurrir que la secuencia de entrada solo se repita una vez ("Suma" consume su secuencia una vez, "Donde" consume su secuencia una vez, "Seleccionar" consume su secuencia una vez y por lo tanto la secuencia de entrada se consume una vez). – jason

+0

Un ejemplo para mostrar que Select y Where no se enumeran por separado requeriría los argumentos para Seleccionar y Dónde tener efectos secundarios notables. –

4

Aquí hay una analogía (debido a Jon Skeet) que podría darle una idea de lo que está sucediendo aquí.

Supongamos que tiene una persona llamada Colección que tiene un paquete de naipes.

Al lado de "Colección" está "X donde X no es una carta de la cara".

Junto a "¿Dónde" es "Seleccionar conversión de valor de la tarjeta a entero"

Al lado de "Seleccionar" es "Sum".

Toca Sum. Sum entra en un bucle.

Sum pokes Seleccionar. Select entra en un bucle.

Seleccionar no tiene nada que dar Suma, por lo que selecione Dónde. Donde entra en un bucle

Where pokes Colección. Manos de colección Donde el Rey de Picas.

Donde lo arroja al suelo y empuja la Colección de nuevo. Manos de la colección Donde la Reina de Diamantes, que tira al suelo. Donde atraviesa la Colección de nuevo y esta vez Colección manos Donde el Tres de Corazones.

Where hands the Three of Hearts to Select. Select extrae el número tres y lo entrega a Sum. Sum suma eso a cero y luego regresa a la parte superior del bucle, y presiona Select nuevamente.

Seleccionar reanuda el ciclo, metiendo Where. Donde se reanuda el ciclo, pulsando Colección una y otra vez hasta que Colección da Donde algo que Donde acepta.

Y así sucesivamente, con la colección de tarjetas de entrega a Dónde, Donde tirarlas o pasarlas a Seleccionar, y Seleccionar números de alimentación a Sumar, que mantiene un total acumulado.

Cuando Colección finalmente dice "no más" a Dónde, Donde dice "no más" para Seleccionar, Seleccionar dice "no más" a Suma, y ​​Sum le devuelve la suma.

+0

Muy buena analogía (Jon, gracias por compartirla Eric), pero el orden de 'Seleccionar' y 'Dónde' se invierten desde el ejemplo del PO. Dicho eso, el punto es claro. – jason

Cuestiones relacionadas