对于 LINQ 选择中的每个
对于那些比我更了解 .Net 内部运作的人来说,这是一个简单的问题::- )。我只是确保我理解一些事情。
在我看来,当您在 foreach 中运行 LINQ 时,会对 LINQ 枚举器进行求值(运行),它返回一个集合,并且 foreach 会对该集合进行处理。但是...仍然,我不确定:
foreach (VCCTreeItem ti in (from treeItems in TreeItems select treeItems))
LINQ 语句是否在每个循环中重新计算(执行)?我认为(并希望)不。但是,在 foreach
中对集合进行操作时,如果集合被修改,您会在运行时收到错误消息。这让我相信幕后可能发生了一些可疑的事情。我从来没有时间详细拆解/检查这个,所以这就是我问你这个的原因。我相信你们中的一些人心里清楚答案 ::- D.
哦,我想我可以问同样的问题:
foreach (VCCTreeItem ti in TreeItems)
如果 TreeItems 是一个属性,我在其中 get
进行一些操作时,该属性将被评估,作为一个值返回,并且 foreach 将对该值进行操作。
Just a quick question for people who know the inner workings of .Net better than me ::- ). I am JUST MAKING SURE that I understand something.
The way I see it, when you run a LINQ in a foreach, the LINQ enumerator is evaluated (run), it returns a collection and the foreach proceeds on that collection. But... still, I am unsure:
foreach (VCCTreeItem ti in (from treeItems in TreeItems select treeItems))
Is the LINQ statement re-evaluated (executed) at each loop? I would think (and hope) that NO. However, when doing operations with a collection in a foreach
, you get error messages at run-time if the collection is modified. Which led me to believe that something fishy may be happening behind the scenes. I never had the time to disassemble / check this in detail, so this is why I'm asking you this. I'm sure some of you know the answer from the top of their head ::- D.
Oh, and I think I can ask the same question about:
foreach (VCCTreeItem ti in TreeItems)
If TreeItems is a property in whose get
I do some operations, the property will be evaluated, returned as a value and the foreach will operate on that value.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
不会重新评估
IEnumerable
。像这样的foreach
语句:对应于此(编辑:
enumerator
也放入using
块中,如 @Double Down 所示):因此,如果您有一些昂贵的操作来生成您正在循环的集合,那么这不是问题;它只会被生产一次。不过,在 LINQ 中,正如 @Double Down 所说,大多数结果都是延迟生成的 - 因此对 GetEnumerator() 的调用几乎不执行任何操作,而结果是通过每次调用 MoveNext( )。总的来说,这与在一次操作中生成整个列表一样耗时,但它节省了内存(永远不会生成包含所有元素的实际
List
;您一次获取一个元素,然后将其丢弃)。The
IEnumerable
is not reevaluated. Aforeach
statement like this:corresponds to this (EDIT:
enumerator
is also put in ausing
block, as shown by @Double Down):So if you have some costly operation that produces the collection you're looping over, it's not a problem; it will only be produced once. In LINQ, though, as @Double Down says, most results are produced lazily - so the call to
GetEnumerator()
does almost nothing, while the result is produced incrementally by each call toMoveNext()
. Overall, this is about as time consuming as producing the entire list in one operation, but it conserves memory (an actualList
containing all elements is never produced; you get one element at a time, then discard it).Linq 正在进行后期绑定评估(使用yield 关键字)。当您在 IEnumerator 中调用 MoveNext() 时,仅对下一个项目进行评估,不会在每次移动下一个调用中从头开始重新计算。
如您所知,您的 foreach 循环的计算结果为
Linq is doing late bound evaluation (using the yield keyword). It's evaluated for only the next item when you call MoveNext() in an IEnumerator, it's not recomputed from scratch in each move next call.
As you already know, your foreach loop evaluates to