第09部分 迭代器
1> 迭代器(iterator)
-
迭代器有时又称光标(cursor)是程序的软件设计模式。迭代器模式提供了一个方法顺序访问一个聚合对象中的各个元素,而不是暴露其内部的标识。
-
在表面效果上来看,是可以在容器对象(例如链表或数组)上遍历访问的接口,设计人员无需关心容器对象的内存分配的实现细节。
-
可以使用foreach遍历的类,都是实现了迭代器的。
2> 标准迭代器的实现方法
-
关键接口:IEnumerator,IEnumerable:using System.Collections;
-
可以同时继承这两个接口实现其中的方法。
-
自定义一个类型,用标准迭代器实现对该类对象的内部聚合对象的遍历,且不暴露其标识。
class CustomList : IEnumerable, IEnumerator
{
private int[] List;
public CustomList(int[] arr)
{
if (arr != null)
{
List = arr;
}
}
private int position = -1;//设置任务
public IEnumerator GetEnumerator()//实现IEnumerable
{
Reset();//复原光标
return this;//继承了IEnumerator,返回自己//返回IEnumerator
}
public bool MoveNext()
//方法表示光标移动到下一个元素,并判断光标是否溢出
{
++position;//表示光标
return position < List.Length;
//当溢出时,表示当前遍历对象以达到最大光标位置。
}
public object Current => List[position];
//当MoveNext返回true时,返回当前光标所在元素的值。
public void Reset()
//重新调用遍历时将光标复原,在GetEnumerator方法中调用。
{
position = -1;
}
}
- GetEnumerator方法实现了IEnumerable接口,返回IEnumerator去进行它的方法,首先会调用Reset()方法将光标复原为-1;
- 其它三个成员实现了IEnumerator的两个方法和一个成员。在foreach遍历时会调用其方法。
class Program
{
static void Main(string[] args)
{
CustomList list = new CustomList(
new int[] {
1, 5, 9, 6, 4, 7, 85, 5, 5 });
foreach (var item in list)//
{
Console.WriteLine(item);
}
}
}
3> 标准实现自定义迭代器附件
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections;
namespace ConsoleApp7
{
class CustomList : IEnumerable, IEnumerator
{
private int[] List;
public CustomList(int[] arr)
{
if (arr != null)
{
List = arr;
}
}
private int position = -1;
public IEnumerator GetEnumerator()//实现IEnumerable
{
Reset();//复原光标
return this;//继承了IEnumerator,返回自己//返回IEnumerator
}
public bool MoveNext()//方法表示光标移动到下一个元素,并判断光标是否溢出
{
++position;//表示光标
return position < List.Length;//当溢出时,表示当前遍历对象以达到最大光标位置。
}
public object Current => List[position];//当MoveNext返回true时,返回当前光标所在元素的值。
public void Reset()//重新调用遍历时将光标复原,在GetEnumerator方法中调用。
{
position = -1;
}
}
class Program
{
static void Main(string[] args)
{
CustomList list = new CustomList(new int[] {
1, 5, 9, 6, 4, 7, 85, 5, 5 });
foreach (var item in list)
{
Console.WriteLine(item);
}
}
}
}
4> foreach遍历的本质
-
先获取in后面这个对象的IEnumerator:会调用对象其中的GetEnumerator方法来获取。
-
执行得到这个IEnumerator对象中的MoveNext(),判定光标的位置并移动。
-
当返回true时,会得到Current的值,并把其赋值给item
5> 用yield return语法糖实现迭代器
-
所谓语法糖(糖衣语法)主要作用时将都咋逻辑简单化,可以增加程序的可读性,从而减少程序的可读性,从而减少程序代码出错的机会。
-
关键接口 IEnumerable
命名空间 using System.Collections;
- 让想要通过foreach遍历的自定义类型实现接口中的方法GetEnumerator即可,
使用yield return系统自动实现标准迭代器的方法逻辑。
- 语法规则: yield 配合 IEnumerable使用,理解为暂时返回并保留当前状态,再次返回时,继续当前状态,直至遍历结束。
class test : IEnumerable
{
private int[] List;
public test(int[] arr)
{
if (arr!=null)
{
List = arr;
}
}
public IEnumerator GetEnumerator()
{
for (int i = 0; i < List.Length; i++)
{
yield return List[i];
}
}
}
5.1 yield语法糖为泛型实现迭代器
- 使用同样的方法foreach迭代,用yield return 控制实现IEnumerable方法GetEnumerator。
转载:https://blog.csdn.net/weixin_52566131/article/details/116427867
查看评论