c#迭代器
一、迭代器
迭代器(iterator)有时又称光标(cursor)是程序设计的软件设计模式
迭代器模式提供一个方法顺序访问一个聚合对象中的各个元素
而又不暴露其内部的标识
二 标准迭代器的实现方法
关键接口:IEnumerator,IEnumerable
命名空间:using System.Collections;
可以通过同时继承IEnumerable和IEnumerator实现其中的方法
IEnumerable表示一个可被遍历的集合(如数组、列表、字典等)
GetEnumerator(),返回一个IEnumerator对象。
实现该接口的类:可以用于foreach循环。
IEnumerator表示遍历过程中的“游标”,记录当前遍历位置,并提供移动下一个、获取当前元素的能力。
核心成员:object Current:获取当前位置的元素。
bool MoveNext():将游标移到下一个元素,如果成功返回true,到达末尾返回false。
void Reset():将游标重置到初始位置(位于第一个元素之前)。
class CustomList : IEnumerable, IEnumerator { private int[] list; //从-1开始的光标 用于表示 数据得到了哪个位置 private int position = -1; public CustomList() { list = new int[] { 1, 2, 3, 4, 5, 6, 7, 8 }; } #region IEnumerable public IEnumerator GetEnumerator() { Reset(); return this; } #endregion public object Current { get { return list[position]; } } public bool MoveNext() { //移动光标 ++position; //是否溢出 溢出就不合法 return position < list.Length; } //reset是重置光标位置 一般写在获取 IEnumerator对象这个函数中 //用于第一次重置光标位置 public void Reset() { position = -1; } }三 用yield return 语法糖实现迭代器
yield return 是C#提供给我们的语法糖
所谓语法糖,也称糖衣语法
主要作用就是将复杂逻辑简单化,可以增加程序的可读性
从而减少程序代码出错的机会
关键接口:IEnumerable
命名空间:using System.Collections;
让想要通过foreach遍历的自定义类实现接口中的方法GetEnumerator即可
class CustomList2 : IEnumerable { private int[] list; public CustomList2() { list = new int[] { 1, 2, 3, 4, 5, 6, 7, 8 }; } public IEnumerator GetEnumerator() { for (int i = 0; i < list.Length; i++) { yield关键字 配合迭代器使用 可以理解为 暂时返回 保留当前的状态 一会还会在回来 C#的语法糖 yield return list[i]; } yield return list[7]; } }四、用yield return 语法糖为泛型类实现迭代器
class CustomList<T> : IEnumerable { private T[] array; public CustomList(params T[] array) { this.array = array; } public IEnumerator GetEnumerator() { for (int i = 0; i < array.Length; i++) { yield return array[i]; } }五 foreach的本质
foreach本质
1.先获取in后面这个对象的 IEnumerator
会调用对象其中的GetEnumerator方法 来获取
2.执行得到这个IEnumerator对象中的 MoveNext方法
3.只要MoveNext方法的返回值时true 就会去得到Current
然后复制给 item
foreach (int item in list) { Console.WriteLine(item); } foreach (int item in list) { Console.WriteLine(item); }