这个linq查询是否在for-each循环的每次迭代中运行?

时间:2008-12-02 02:34:45

标签: linq enumeration

在关于SO的另一个问题中,我回答了类似下面的代码并得到了一个评论,即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

3 个答案:

答案 0 :(得分:7)

不...在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。

答案 1 :(得分:1)

我相信它会在第一次到达时运行,并产生一个具有所有匹配值的枚举。你实际得到的是该枚举的枚举器。

答案 2 :(得分:0)

我查找了FOR EACH ... NEXT语句,看起来Visual Basic只在循环开始之前对集合进行一次计算,因此它不应该在每次迭代时运行查询。

  

迭代次数。 Visual Basic   仅对集合进行一次评估,   在循环开始之前。如果你的   语句块更改元素或   组,这些变化不影响   迭代循环。