1、迭代器是什么
- 迭代器(iterator)又称 游标 / 光标(cursor)
- 是程序设计的软件设计模式
- 迭代器模式提供一个方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部标识
从表面上看:
迭代器是可以在容器对象(例如链表、数组等)上遍历的接口。
设计人员无需关心容器对象的内存分配的实现细节。
可以用
foreach
遍历的类,都是实现了迭代器的。
2、标准迭代器的实现方法
- 关键接口:
IEnumerable
和IEnumerator
- namespace:
using System.Collections;
- 可以通过同时继承两个接口实现其中的方法
- namespace:
- Demo:
using System.Collections;
// demo类
class MyList : IEnumerable, IEnumerator
{
private int[] list;
private int position = -1; // 游标
// IEnumerator 的 Current
public object Current
{
get { return list[position]; }
}
public MyList() {
list = new int[]{ 1, 5, 20, 9, 2, 77 };
}
// 实现 IEnumerable 的方法
public IEnumerator GetEnumerator()
{
Reset();
return this;
}
// 实现 IEnumerator 的 MoveNext 方法
public bool MoveNext()
{
++position;
return position < list.Length;
}
// 实现 IEnumerator 的 Reset 方法
public void Reset()
{
position = -1;
}
}
// 测试代码
MyList myList = new MyList();
/**
* foreach本质:
* 1、调用 in 后面对象的 GetEnumerator 方法获取 IEnumerator
* 小注:其实继不继承 IEnumerable 不重要,主要是要有能获取 IEnumerator 的 GetEnumerator 方法
* 2、执行对象实现的 IEnumerator 接口的 MoveNext 方法
* 3、只要 MoveNext 返回 true,就会得到 IEnumerator 的 Current 并赋值给 item
* 小注:返回 false 就结束循环
*/
foreach (var item in myList)
{
Console.WriteLine(item); // 完美遍历!~
}
3、用 yield return 语法糖实现迭代器
yield return
是C#提供的语法糖- 关键接口:
IEnumerable
- namespace:
using System.Collections;
- 实现接口中的
GetEnumerator
方法即可
class MyNewList : IEnumerable
{
private int[] list;
public MyNewList()
{
list = new int[] { 6, 22, 7, 13, 32, 99, 0 };
}
// 只需要实现 GetEnumerator 方法即可
public IEnumerator GetEnumerator()
{
for (int i = 0; i < list.Length; i++)
{
/** 语法糖~
* yield 关键字 配合迭代器使用
* 可以理解为 暂时返回,保留当前状态
*/
yield return list[i];
}
}
}
4、用 yield return 语法糖为泛型类实现迭代器
没啥好讲的,直接上代码
class MyNewTList<T> : IEnumerable
{
private T[] list;
public MyNewTList(params T[] list)
{
this.list = list;
}
public IEnumerator GetEnumerator()
{
for (int i = 0; i < list.Length; i++)
{
yield return list[i];
}
}
}
// 测试代码
MyNewTList<string> myNewTList = new MyNewTList<string>("aaa", "bbb", "ccc");
foreach (var item in myNewTList)
{
Console.WriteLine(item); // 完美遍历!~
}