一、迭代器
迭代器(iterator)有时又称光标(cursor)是程序设计的软件设计模式
迭代器模式提供一个方法顺序访问一个聚合对象中的各个元素
而又不暴露其内部的标识
二 标准迭代器的实现方法
关键接口:IEnumerator,IEnumerable
命名空间:using System.Collections;
可以通过同时继承IEnumerable和IEnumerator实现其中的方法
IEnumerable表示一个可被遍历的集合(如数组、列表、字典等)
GetEnumerator(),返回一个 IEnumerator 对象。
实现该接口的类 :可以用于 foreach 循环。
IEnumerator 表示遍历过程中的"游标",记录当前遍历位置,并提供移动下一个、获取当前元素的能力。
核心成员 :object Current:获取当前位置的元素。
bool MoveNext():将游标移到下一个元素,如果成功返回 true,到达末尾返回 false。
void Reset():将游标重置到初始位置(位于第一个元素之前)。
cs
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即可
cs
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 语法糖为泛型类实现迭代器
cs
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
cs
foreach (int item in list)
{
Console.WriteLine(item);
}
foreach (int item in list)
{
Console.WriteLine(item);
}