2008-12-02 9 views
6

En otra pregunta sobre SO, respondí con un código como el siguiente y recibí un comentario de que la consulta LINQ probablemente se evaluó en cada iteración de for/each. ¿Es eso cierto?¿Se ejecuta esta consulta linq en cada iteración del bucle for-each?

Sé que LINQ-querys no se ejecuta antes de que se evalúen sus elementos, por lo que parece posible que esta forma de iterar el resultado pueda hacer que se ejecute en cada iteración.

Dim d = New Dictionary(Of String, String)()  
d.Add("Teststring", "Hello")  
d.Add("1TestString1", "World")  
d.Add("2TestString2", "Test")  

For Each i As String In From e In d Where e.Value.StartsWith("W") Select e.Key 
    MsgBox("This key has a matching value:" & i)  
Next 
+0

Bueno, parece que lo que tenía está bien, pero al menos formatee al final de la línea _ por lo que no está en una línea grande :) –

+0

Sí. Esta evaluación tardía con LINQ tomará un tiempo para familiarizarse. – Stefan

+0

Sí, lo hace ... pero es genial una vez que lo tienes, puedes hacer algunas cosas bastante dulces. –

Respuesta

7

NO ... en un foreach, el "GetEnumerator" se llama solo una vez (siempre), y eso se usa en el futuro.

EDIT: pongo una declaración aquí sobre el conjunto de resultados almacenado temporalmente ... eso solo es cierto para algunos casos ... no este, entonces lo saqué.

EDIT: Por favor, perdona esta por ser demasiado prolijo ... pero quería espectáculo de lo que está pasando ... así que aquí tiene una aplicación de consola :)

using System; 
using System.Collections.Generic; 
using System.Linq; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      foreach (string item in MyCustomEnumerator() 
       .Where(item => item.StartsWith("abc"))) 
      { 
      Console.WriteLine(item); 
      } 
     } 

     static IEnumerable<string> MyCustomEnumerator() 
     { 
      Console.WriteLine(DateTime.Now); 

      yield return "abc1"; 

      Console.WriteLine(DateTime.Now); 

      yield return "abc2"; 

      Console.WriteLine(DateTime.Now); 

      yield return "abc3"; 

      Console.WriteLine(DateTime.Now); 

      yield return "xxx"; 
     } 
    } 
} 

EDIT: Esto resultará en un DateTime, luego abc1, luego un DateTime, luego abc2, luego un DateTime, luego abc3, luego un DateTime.

+2

Gracias. Y pheuw. Utilicé esa forma de iterar mucho a través de los resultados de LINQ en un proyecto reciente. ;) – Stefan

0

busqué la PARA CADA ... NEXT y parece que Visual Basic evalúa la colección sólo una vez, antes de que comience el bucle, por lo que no se debe ejecutar la consulta en cada iteración.

Número de iteraciones. Visual Basic evalúa la colección solo una vez, antes de que comience el ciclo. Si el bloque de instrucciones cambia el elemento o el grupo , estos cambios no afectan a la iteración del ciclo.

1

Creo que se ejecutará la primera vez que se llegue y se obtendrá una enumeración que tenga todos los valores coincidentes. Lo que realmente obtendrá es un enumerador para esa enumeración.

Cuestiones relacionadas