Sorry, your browser cannot access this site
This page requires browser support (enable) JavaScript
Learn more >

迭代器

一、定义

迭代器(iterator)有时又称光标(cursor) 是程序设计的软件设计模式 迭代器模式提供一个方法顺序访问一个聚合对象中的各个元素 而又不暴露其内部的标识

在表现效果上看 是可以在容器对象(例如链表或数组)上遍历访问的接口 设计人员无需关心容器对象的内存分配的实现细节 可以用 foreach 遍历的类,都是实现了迭代器的

二、标准实现迭代器

  • 关键接口:IEnumerator,IEnumerable
  • 命名空间:using system.collections;
  • 可以通过同时继承 IEnumerable 和 IEnumerator 实现其中的方法

foreach 本质

  1. 先获取 in 后面这个对象的 IEnumerator,会调用对象其中的 GetEnumerator 方法 来获取
  2. 执行得到这个 IEnumerator 对象中的 MoveNext 方法
  3. 只要 MoveNext 方法的返回值时 true 就会去得到 current 然后复制给 item
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
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 即可
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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];
}
}
}

评论