gpt4 book ai didi

c# - 为什么 linq 不实现完全懒惰?

转载 作者:行者123 更新时间:2023-11-30 19:24:00 26 4
gpt4 key购买 nike

我有以下代码,我认为它会起作用:

static int ComputerFailsOnTrue(bool flag)
{
if (flag)
throw new Exception();
return 10; // not relevant
}

static IEnumerable<double> StartComputer()
{
yield return ComputerFailsOnTrue(true);
yield return ComputerFailsOnTrue(false);
yield return ComputerFailsOnTrue(false);
}

static public void Main()
{
foreach (var item in StartComputer().Skip(1))
{
Console.WriteLine($"Hey {item}");
}
Console.ReadLine();
}

但它失败了(我会得到异常),因为集合的第一个元素将被计算。为什么给定集合中枚举器的 moveNext 方法总是计算当前元素?是否假设当前的计算可以依赖于先前的状态?

最佳答案

这并不是 LINQ 本身的失败。这是一个与两件事相关的问题 - IEnumerator<T> interface和 C# 的 iterator methods .

IEnumerator<T>只有两个有趣的成员 - MoveNextCurrent .执行Skip的唯一方法在这样的接口(interface)之上1 是调用MoveNext与您希望跳过的项目数一样多的次数,当然还有 MoveNext 的任何实现可以在每次方法调用时自由运行任意代码。它能做的是避免访问 Current .

在 C# 的迭代器实现中,它“自动”生成 IEnumerable<T> 的实现。和 IEnumerator<T> , MoveNextCurrent密切相关 - 你只写一个方法,每次该方法获得控制权(对于 MoveNext ),它还必须计算下一个 Current值(value)。

如果您正在实现 IEnumerator<T>手动,你可以自由地在你的 MoveNext 中放置一些逻辑Current 中的方法和一些逻辑属性(property),包括评估Current懒惰的。在这样的实现中,如果调用 compute(true)是您实现 Current 的一部分,您的代码将按预期工作。


1LINQ 中可能有一些专门化,可以绕过对内置集合类使用枚举器,但一般来说,这是使用的接口(interface)。

关于c# - 为什么 linq 不实现完全懒惰?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41636796/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com