对于 LINQ 选择中的每个

发布于 2024-10-19 06:44:27 字数 614 浏览 1 评论 0原文

对于那些比我更了解 .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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

伤痕我心 2024-10-26 06:44:27

不会重新评估 IEnumerable。像这样的 foreach 语句:

IEnumerable<Foo> enumerable = ...;
foreach (Foo f in enumerable) {
    ...
}

对应于此(编辑:enumerator 也放入 using 块中,如 @Double Down 所示):

IEnumerable<Foo> enumerable = ...;
IEnumerator<Foo> enumerator = enumerable.GetEnumerator();
while (enumerator.MoveNext()) {
    Foo f = enumerator.Current;
    ...
}

因此,如果您有一些昂贵的操作来生成您正在循环的集合,那么这不是问题;它只会被生产一次。不过,在 LINQ 中,正如 @Double Down 所说,大多数结果都是延迟生成的 - 因此对 GetEnumerator() 的调用几乎不执行任何操作,而结果是通过每次调用 MoveNext( )。总的来说,这与在一次操作中生成整个列表一样耗时,但它节省了内存(永远不会生成包含所有元素的实际 List;您一次获取一个元素,然后将其丢弃)。

The IEnumerable is not reevaluated. A foreach statement like this:

IEnumerable<Foo> enumerable = ...;
foreach (Foo f in enumerable) {
    ...
}

corresponds to this (EDIT: enumerator is also put in a using block, as shown by @Double Down):

IEnumerable<Foo> enumerable = ...;
IEnumerator<Foo> enumerator = enumerable.GetEnumerator();
while (enumerator.MoveNext()) {
    Foo f = enumerator.Current;
    ...
}

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 to MoveNext(). Overall, this is about as time consuming as producing the entire list in one operation, but it conserves memory (an actual List containing all elements is never produced; you get one element at a time, then discard it).

戈亓 2024-10-26 06:44:27

Linq 正在进行后期绑定评估(使用yield 关键字)。当您在 IEnumerator 中调用 MoveNext() 时,仅对下一个项目进行评估,不会在每次移动下一个调用中从头开始重新计算。

如您所知,您的 foreach 循环的计算结果为

using (var enumerator = enumerable.GetEnumerator())
{
    while (enumerator.MoveNext())
    {
        // Loop body.
    }
}

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

using (var enumerator = enumerable.GetEnumerator())
{
    while (enumerator.MoveNext())
    {
        // Loop body.
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文