2008-12-02 73 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

我相信它会在第一次运行时产生一个包含所有匹配值的枚举。你实际上会得到的是枚举的枚举器。