迭代器
迭代器(iterator)是一种对象,用来遍历容器中部分或全部的元素.
拿foreach的内部实现来举例。foreach可以用来遍历可枚举类型集合的元素,比如:数组,list,dictionary等
其实就是用while语句来获取遍历集合的 IEnumerator接口 来不断的Movenext()(后面会介绍)来实现的.
首先创建个类,继承两个接口:IEnumerator、IEnumerable.
public class Test : IEnumerator,IEnumerable
{
public object Current => throw new NotImplementedException();
public IEnumerator GetEnumerator()
{
throw new NotImplementedException();
}
public bool MoveNext()
{
throw new NotImplementedException();
}
public void Reset()
{
throw new NotImplementedException();
}
}
- IEnumerator实现MoveNext()、Reset()方法。MoveNext()是用来讲集合下标下移一个单位,并且检测当前迭代器是否越界返回 bool。Reset()则是当你多次使用迭代器时不可能每次下标都从上次开始吧,所以在每次获取迭代器时都要将它重置,这个函数就是这个作用。。。
- Current的用来获取当前下标所指向的该类元素
- IEnumerable实现GetEnumerator()方法.这个方法用来获取该类迭代器。
下面将它们分别实现:
class CustomList01 : IEnumerator, IEnumerable
{
private int[] list;
private int position = -1;
public CustomList01()
{
list = new int[] { 1, 2, 3, 4, 0 };
}
public object Current
{
get
{
return list[position];
}
}
// IEnumerable
public IEnumerator GetEnumerator()
{
Reset();
return this;
}
//IEnumerable
public bool MoveNext()
{
position++;
return position < list.Length;
}
public void Reset()
{
position = -1;
}
}
下面是它的使用:
CustomList01 customList01 = new CustomList01();
IEnumerator enumerator = customList01.GetEnumerator();
if(enumerator.MoveNext())
{
Console.WriteLine("元素: "+ enumerator.Current);
}
运行结果:
因为这里只进行了一次MoveNext所以只打印出了这一个元素,全部打印也很简单,只需加个while循环
while(enumerator.MoveNext())
{
Console.WriteLine("元素: " + enumerator.Current);
}
结果:
到这里,迭代器的标准实现已经完成,其实foreach的底层实现就类似上面写的while一坨代码
可能还会有人想知道泛型的迭代器如何写,同时迭代器还有简单协程的写法,下面就一起带过吧
class CustomList02<T> : IEnumerable
{
private T[] list;
//params 可接受多个参数(一维型)
public CustomList02(params T[] array )
{
this.list = array;
}
public IEnumerator GetEnumerator()
{
for (int i = 0; i < list.Length; i++)
{
yield return list[i];
}
}
}
void Main()
{
CustomList02<int> customList011 =
new CustomList02<int>(1, 1, 2, 3);
foreach (int item in customList011)
{
Console.WriteLine("泛型元素: " + item);
}
}