C#实现迭代器

Posted 小小架构师

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C#实现迭代器相关的知识,希望对你有一定的参考价值。

迭代器模式(Iterator),提供一种方法顺序访问一个聚合对象中的各种元素,而又不暴露该对象的内部表示。C#中使用 IEnumerator 接口实现,Java中使用 Iterator 接口实现,其中原理都差不多,下面我就用C#代码来演示下迭代器的实现。
假如我要实现一个自定义容器列表,就叫它 SpecialList 吧,可以实现类似 ArrayList 的功能。如下:
这个时候我想遍历这个列表,当我使用 foreach 的时候,报错了。如下:
C#实现迭代器
提示 SpecialList 不包含 GetEnumerator 的公共实例定义,在C#中,如果想要使用foreach遍历列表对象,这个列表对象必须要实现 IEnumerable 的Get Enumerator() 方法,我们来加一下。如下:
C#实现迭代器
继承后, foreach 列表的时候就不会再报错了,但我们并没有实现 GetEnumerator() 这个方法。我们看一下这个方法的返回值类型为 IEumerator ,F12进去看一下这个接口的定义。如下:
C#实现迭代器
这个接口里面有两个方法和一个属性。其中 MoveNext() 是最核心的方法,就是在这个里面实现列表的遍历。话不多说,我们先定义一个继承 IEnumerator 的类,就叫 SpecialEnumerator 吧。如下:
C#实现迭代器
不好意思,我已经简单的写好这个类了,那就简单的讲一个这个类的原理吧。 SpecialEnumerator 主要定义了一个 SpecialList 类型的 _list ,还有当前元素的 _current ,还有当前索引的 _index 。我们重点看一下 MoveNext 方法,里面的代码其实也非常简单,就是判断_index是否已经到底,没有的话叫取出当前_index上的元素赋予 _cuurent ,然后返回true,这里的返回值给到 foreach ,如果为true,则继续遍历,如果为false,则 foreach 跳出循环。我们再来看一下 SpecialList 中怎么使用 SpecialEnumerator 类。如下:
C#实现迭代器
这样只是返回 SpecialEnumerator 的一个实例,同时将当前要枚举的列表对象(this)传入进去。你可能会有疑问,这里只是返回一个对象,在 foreach 中并没有循环判断 MoveNext 是true还是false的代码,那它是怎么实现的呢?其实 foreach 只是一个语法糖,它本质上其实是使用了 while 语法来实现的。如下:
C#实现迭代器
到这里,相信大家已经明白迭代器是怎么实现的了。最后再补充一下,大家可能会觉得额外实现 SpecialEnumerator 类比较繁琐,其实如果你的列表遍历规则比较简单的话,可以使用 yield 语法来代替 SpecialEnumerator 类,只要这样写就行。如下:
但如果你的列表遍历规则比较特殊,比如像栈、队列这样的容器类时,还是建议实现枚举类,这样可以将遍历规则封装在 MoveNext 中。

更多精彩内容,可关注我的公众号:


以上是关于C#实现迭代器的主要内容,如果未能解决你的问题,请参考以下文章

从C#走进Python迭代器

通过Lua迭代器自定义实现对c#集合的遍历

C#实现迭代器

C#迭代器实现

C# 自定义迭代器实现

C# Iterator迭代器的实现方式