对于那些比我更了解.Net内部工作原理的人来说,这只是一个简单的问题:: - ).我只是确定我明白了什么.
我看到它的方式,当你在foreach中运行LINQ时,LINQ枚举器被评估(运行),它返回一个集合,foreach继续在该集合上进行.但是......我仍然不确定:
foreach (VCCTreeItem ti in (from treeItems in TreeItems select treeItems))
Run Code Online (Sandbox Code Playgroud)
是否在每个循环中重新评估(执行)LINQ语句?我会想(并希望)不.但是,在对a中的集合执行操作foreach时,如果修改了集合,则会在运行时收到错误消息.这让我相信在幕后可能会发生一些可疑的事情.我从来没有时间详细拆解/检查这个,所以这就是我问你的原因.我相信你们中的一些人从头顶知道答案:: - D.
哦,我想我可以问同样的问题:
foreach (VCCTreeItem ti in TreeItems)
Run Code Online (Sandbox Code Playgroud)
如果TreeItems是get我执行某些操作的属性,则将对属性进行求值,作为值返回,并且foreach将对该值进行操作.
在IEnumerable没有重新评估.这样的foreach陈述:
IEnumerable<Foo> enumerable = ...;
foreach (Foo f in enumerable) {
...
}
Run Code Online (Sandbox Code Playgroud)
对应于此(编辑:enumerator也放在一个using块中,如@Double Down所示):
IEnumerable<Foo> enumerable = ...;
IEnumerator<Foo> enumerator = enumerable.GetEnumerator();
while (enumerator.MoveNext()) {
Foo f = enumerator.Current;
...
}
Run Code Online (Sandbox Code Playgroud)
因此,如果你有一些昂贵的操作产生你正在循环的集合,那不是问题; 它只会生产一次.但是在LINQ中,正如@Double Down所说的那样,大多数结果是懒散产生的 - 所以调用GetEnumerator()几乎没有任何结果,而结果是每次调用时逐渐产生的MoveNext().总的来说,这与在一个操作中生成整个列表一样耗时,但它节省了内存(List从不生成包含所有元素的实际内容;您一次获得一个元素,然后丢弃它).