c# - 使用 yield return 来描述一个迭代器
问题描述
如果有人检查了我对这个主题的想法并纠正了他们的错误,我将不胜感激。我希望这种类型的“请检查我的想法”不会太违反网站的规则,我的问题更多是试图从一个不太了解的人那里回答某个主题是如何工作的话题。希望它对像我这样的初学者来说可能是有价值的/有见地的,并且可能希望看到对正在发生的事情进行高级但非常基本的描述。
这是我理解主题IEnumerable
和IEnumerator
收益回报的方法。
方式IEnumerable
和IEnumerator
交互非常清晰和自然——我们有两个对象,一个包含集合,一个包含光标。
目前,让我们忽略 yield return 和两个接口之间的联系,只考虑以下概念/问题 - 假设我们的代码在每一行都有一个整数的表达式/计算,我们想创建一个函数f
它按顺序执行并返回这些整数,即我们第一次调用f()
它将返回在第一行计算的整数,第二次调用它将返回第二个整数,等等。这样做的自然方法是创建某种包含上述代码的辅助类/对象,但除此之外,它还将存储我们在代码中的位置。使用goto
这是可以做到的。为了实现这一点,我们指定了一个 yield return 关键字来执行此操作 - 编译器认识到,如果我们有某种代码块,其中包含 yield return,它将为其创建一个帮助器/控制器类。请注意,这个帮助程序类如何作用于代码块已经非常类似于 anIEnumerator
作用于IEnumerable
什么——它在某种意义上存储了我们所在的“位置”。
接下来我们将使用这个概念并对其进行定义,使其与现有的功能IEnumerator
和IEnumerable
接口一致。我们将瞄准的基本功能是foreach
- 当与实现IEnumerable
接口的对象一起使用时,它返回在IEnumerator
via中实现的光标IEnumerable.GetEnumerator
,然后使用 和 的方法沿着集合移动MoveNext
并current
返回分别指向的对象。
所以我们可以使用这个概念的第一种方法是只定义GetEnumerator
- 我们简单地将我们想要顺序执行的代码块放在GetEnumerator
. 为此,编译器认识到,如果GetEnumerator
contains的主体yield return
,它将创建一个辅助对象(并将此对象返回给最后的调用GetEnumerator
),并且此辅助类还将实现方法MoveNext
和Current
作为“执行下一行,并分别保存到_current
(辅助类的某个字段)和“返回_current
”。本质上,GetEnumerator
将返回上面两段提到的辅助对象,此外编译器将创建所需的MoveNext
和Current
这个帮助对象中的方法,以便它们沿着代码块移动,分别返回值。
我们可以使用该概念的另一种方式是直接“定义”集合并遍历它。所以这一次,我们不只是返回一个IEnumerator
/ 助手类,而是返回一个IEnumerable
. 但就我们的目的而言,我们真的只是对能够将此对象与foreach
. 因此,我们可以做到这一点的一种方法是只做与上面几乎相同的事情——我们将辅助对象实现为 an IEnumerable
as IEnumerator
——所以我们可以IEnumerable
在某些foreach
语句中将它作为 an 返回,并且我们将 the 实现GetEnumerator
为只是 return this
。所以效果和上面的很相似。
上面说的有道理吗?我不清楚的一件事是例如是否foreach
可以以某种方式IEnumerator
直接使用 - 即我们是否可以执行(foreach element in Enumerator())
whereEnumerator()
是一个IEnumerator
仅返回的函数,而不是IEnumerable
. 这没有意义,但我不确定编译器是否无法弄清楚这些事情 - 特别是因为如果它yield return
在体内看到它能够决定做如此截然不同的事情,然后它会创建一个辅助对象等,就像我提到的那样,所以我不确定除此之外还有多少其他语法糖。
解决方案
推荐阅读
- scala - Scala 中集合的交集
- android - Android Studio 更改工具栏阴影颜色
- javascript - 如何在不刷新网页的情况下运行 php 文件?
- maven - 未找到 hbase spark 模块
- github-actions - 基于不同分支推送构建和推送到不同 ECR 的 GitHub CI 脚本
- javascript - 图片出现瞬间消失
- python - Python - 读取每一行文本文件并将每一行传递给变量
- javascript - OnClick 功能在 Chrome 上不起作用?
- apache-spark - 无法将 Dataframe 结果写入 Hive 表/LFS 文件
- discord - 投票问题,增加正确数量的反应。(d.py)