In another question on SO I answered with code like the one below and got a comment that the LINQ-query probably was evaluated in every iteration of the for/each. Is that true?
在关于SO的另一个问题中,我回答了类似下面的代码,得到了一个评论,即LINQ查询可能在for / each的每次迭代中都得到了评估。真的吗?
I know that LINQ-querys does not executes before its items is evaluated so it seems possible that this way to iterate the result can make it run on every iteration?
我知道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 个解决方案
#1
7
NO... in a foreach, the "GetEnumerator" is called only once (ever), and that is used going forward.
不......在foreach中,“GetEnumerator”只被调用一次(永远),并且在未来使用。
EDIT: I put a statement here about the result set being stored temporarily... that's only true for some cases... not this one, so I took it out.
编辑:我在这里写了一个关于临时存储结果集的声明......这只适用于某些情况......不是这个,所以我把它拿出来了。
EDIT: Please forgive this for being overly verbose... but I wanted to show you what is happening... so here's a Console 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: This will result in a DateTime, then abc1, then a DateTime, then abc2, then a DateTime, then abc3, then a DateTime.
编辑:这将导致DateTime,然后是abc1,然后是DateTime,然后是abc2,然后是DateTime,然后是abc3,然后是DateTime。
#2
1
I believe that it will run the first time it is reached and produce an enumeration that has all the matching values. What you will actually get back is an enumerator for that enumeration.
我相信它将在第一次到达时运行并生成具有所有匹配值的枚举。你实际得到的是该枚举的枚举器。
#3
0
I looked up the FOR EACH...NEXT statement and it seems like Visual Basic evaluates the collection only once, before the loop begins, so it should not run the query on every iteration.
我查找了FOR EACH ... NEXT语句,看起来Visual Basic只在循环开始之前评估集合一次,所以它不应该在每次迭代时运行查询。
Number of Iterations. Visual Basic evaluates the collection only once, before the loop begins. If your statement block changes element or group, these changes do not affect the iteration of the loop.
迭代次数。在循环开始之前,Visual Basic仅对集合进行一次计算。如果语句块更改了元素或组,则这些更改不会影响循环的迭代。
#1
7
NO... in a foreach, the "GetEnumerator" is called only once (ever), and that is used going forward.
不......在foreach中,“GetEnumerator”只被调用一次(永远),并且在未来使用。
EDIT: I put a statement here about the result set being stored temporarily... that's only true for some cases... not this one, so I took it out.
编辑:我在这里写了一个关于临时存储结果集的声明......这只适用于某些情况......不是这个,所以我把它拿出来了。
EDIT: Please forgive this for being overly verbose... but I wanted to show you what is happening... so here's a Console 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: This will result in a DateTime, then abc1, then a DateTime, then abc2, then a DateTime, then abc3, then a DateTime.
编辑:这将导致DateTime,然后是abc1,然后是DateTime,然后是abc2,然后是DateTime,然后是abc3,然后是DateTime。
#2
1
I believe that it will run the first time it is reached and produce an enumeration that has all the matching values. What you will actually get back is an enumerator for that enumeration.
我相信它将在第一次到达时运行并生成具有所有匹配值的枚举。你实际得到的是该枚举的枚举器。
#3
0
I looked up the FOR EACH...NEXT statement and it seems like Visual Basic evaluates the collection only once, before the loop begins, so it should not run the query on every iteration.
我查找了FOR EACH ... NEXT语句,看起来Visual Basic只在循环开始之前评估集合一次,所以它不应该在每次迭代时运行查询。
Number of Iterations. Visual Basic evaluates the collection only once, before the loop begins. If your statement block changes element or group, these changes do not affect the iteration of the loop.
迭代次数。在循环开始之前,Visual Basic仅对集合进行一次计算。如果语句块更改了元素或组,则这些更改不会影响循环的迭代。