2008-12-02 4 views
6

In einer weiteren Frage zu SO antwortete ich mit Code wie dem untenstehenden und bekam einen Kommentar, dass die LINQ-Abfrage wahrscheinlich in jeder Iteration des for/each ausgewertet wurde. Ist das wahr?Wird diese linq-Abfrage bei jeder Iteration der for-each-Schleife ausgeführt?

Ich weiß, dass LINQ-Querys nicht ausgeführt wird, bevor ihre Elemente ausgewertet wird, so scheint es möglich, dass diese Möglichkeit, das Ergebnis zu iterieren, es auf jeder Iteration ausführen kann?

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

Nun, es sieht aus wie das, was Sie hatten, ist in Ordnung, aber zumindest Format mit Ende der Zeile _ so ist es nicht auf einer großen Linie :) –

+0

Yeah. Diese späte Bewertung mit LINQ wird eine Weile dauern, bis Sie sich damit vertraut machen. – Stefan

+0

Ja, tut es ... aber es ist toll, wenn du es einmal hast, kannst du ziemlich süßes Zeug machen. –

Antwort

7

NO ... in einer foreach, der "GetEnumerator" wird nur einmal (immer) aufgerufen, und das wird weiter verwendet.

EDIT: Ich habe hier eine Aussage über das Ergebnis Set vorübergehend gespeichert ... das ist nur in einigen Fällen wahr ... nicht dieses, also nahm ich es heraus.

EDIT: Bitte verzeihen Sie dies für allzu weitschweifig zu sein ... aber ich wollte zeigen Sie, was passiert ... also hier ist eine Konsole app :)

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: Dies führt zu eine DateTime, dann abc1, dann eine DateTime, dann abc2, dann eine DateTime, dann abc3, dann eine DateTime.

+2

Danke. Und pheuw. Ich habe diesen Weg genutzt, um LINQ-Ergebnisse in einem kürzlichen Projekt zu wiederholen. ;) – Stefan

0

Ich sah auf die FOR EACH ... NEXT-Anweisung und es scheint, wie Visual Basic die Sammlung nur einmal ausgewertet wird, bevor die Schleife beginnt, so sollte es die Abfrage bei jeder Iteration nicht ausgeführt werden.

Anzahl der Iterationen. Visual Basic wertet die Sammlung nur einmal, aus, bevor die Schleife beginnt. Wenn Ihr Anweisungsblock Element oder Gruppe ändert, haben diese Änderungen keinen Einfluss auf die Iteration der Schleife.

1

Ich glaube, dass es beim ersten Mal ausgeführt wird und eine Aufzählung erzeugt, die alle übereinstimmenden Werte aufweist. Was Sie tatsächlich zurückbekommen, ist ein Enumerator für diese Enumeration.