2008-12-02 75 views
6

在另一個問題上,我用下面的代碼回答了問題,並得到了一個評論:LINQ查詢可能是在for/each的每次迭代中評估的。真的嗎?這個linq查詢是否在for-each循環的每個迭代上運行?

我知道LINQ-querys在其項目被評估之前不會執行,所以似乎有可能這種迭代結果的方式可以讓它在每次迭代中運行?

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

那麼它看起來像你有什麼好,但至少格式結束_所以它不是在一大行:) – 2008-12-02 03:28:31

+0

是的。對於LINQ來說,這個遲到的評估工作需要一段時間才能熟悉。 – Stefan 2008-12-02 03:37:09

回答

7

NO ...在foreach中,「GetEnumerator」只被調用一次(永遠),並且這被用於向前。

編輯:我在這裏陳述關於臨時存儲的結果集......這隻對某些情況是正確的...不是這個,所以我把它拿出來。

編輯:請原諒這對於過於冗長......但我想顯示你發生了什麼......所以這裏是一個控制檯應用程序:)

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"; 
     } 
    } 
} 

編輯:這將導致一個DateTime,然後是abc1,然後是DateTime,然後是abc2,然後是DateTime,然後是abc3,然後是DateTime。

0

我擡頭爲每條... Next語句,它似乎像Visual Basic計算集合只有一次,在循環開始前,所以它不應該運行在每次迭代查詢。

迭代次數。在循環開始之前,Visual Basic 僅對集合進行一次評估,即 。如果您的 語句塊更改元素或 組,則這些更改不會影響循環的迭代。

1

我相信它會在第一次運行時產生一個包含所有匹配值的枚舉。你實際上會得到的是枚舉的枚舉器。