当前位置: 首页 > news >正文

迭代器模式(IteratorPattern)

文章目录

  • 1.迭代器模式定义
  • 2.UML类图
  • 3.C# 中的迭代器
  • 4.代码实现
  • 5.使用yield简化迭代器代码

1.迭代器模式定义

能在不暴露集合(列表、栈、树等)底层表现形式的情况下遍历集合所有元素
er)
在这里插入图片描述

2.UML类图

在这里插入图片描述

  1. 迭代器 (Iterator): 接口声明了遍历集合所需的操作: 获取下一个元素、 获取当前位置和重新开始迭代等。
  2. 具体迭代器 (Concrete Iterators): 实现遍历集合的一种特定算法。 迭代器对象必须跟踪自身遍历的进度。 这使得多个迭代器可以相互独立地遍历同一集合。
  3. 集合 (Collection): 接口声明一个或多个方法来获取与集合兼容的迭代器。 请注意, 返回方法的类型必须被声明为迭代器接口, 因此具体集合可以返回各种不同种类的迭代器。
  4. 具体集合 (Concrete Collections): 会在客户端请求迭代器时返回一个特定的具体迭代器类实体

3.C# 中的迭代器

在这里插入图片描述

  1. 集合要实现IEnuerable接口,实现GetEnumerator方法,这个成员方法会返回一个IEnumerator对象,这个对象就是我们的迭代器;
  2. 迭代器实现IEnumerator接口,这个接口只有三个方法:MoveNext方法用于判断是否已经到达了迭代的终点,Current属性用于获取当前迭代的值,Reset方法用于重置迭代器。
  3. 此外,这两个类分别还有对应的泛型类。IEnumerator为了实现对特定对象的释放,又额外继承了IDisposable接口。

4.代码实现

我这里的迭代器类和集合类使用了C#自带的IEnumerator和IEnumerable借口
具体迭代器:

public class MyRangeIterator : IEnumerator<int>
{int end;int cur;public MyRangeIterator(MyRange parent){this.end = parent.end;this.cur = parent.start;}public int Current => cur;object IEnumerator.Current => Current;public void Dispose() { }public bool MoveNext(){Console.WriteLine("MyRangeIterator MoveNext : " + cur);return ++cur <= end;}public void Reset() { }
}

具体集合:

public class MyRange : IEnumerable<int>
{private int start, end;public MyRange(int start, int end){this.start = start;this.end = end;}public IEnumerator<int> GetEnumerator(){return new MyRangeIterator(this);//待实现}IEnumerator IEnumerable.GetEnumerator(){return GetEnumerator();}
}

使用:

var range = new MyRange(1,5);
Console.WriteLine("new range");
range.Foreach(i =>
{Console.WriteLine("print : " + i);
});

new range
MyRangeIterator MoveNext : 1
print : 2
MyRangeIterator MoveNext : 2
print : 3
MyRangeIterator MoveNext : 3
print : 4
MyRangeIterator MoveNext : 4
print : 5
MyRangeIterator MoveNext : 5

5.使用yield简化迭代器代码

class MyRange : IEnumerable<int>
{private int start, end;public MyRange(int start, int end){this.start = start;this.end = end;}public IEnumerator<int> GetEnumerator(){for (int i = start+1; i <= end; i++)//注意这里,直接使用一个循环替代了前面的迭代器{yield return i;}}IEnumerator IEnumerable.GetEnumerator(){return GetEnumerator();}
}
  • yield关键字用于返回值为IEnumerable、IEnumerator、IEnumerable、IEnumerator函数中,它有两个使用方法,yield break和yield return。
  • 返回值为IEnumerable、IEnumerator、IEnumerable、IEnumerator的函数会自动生成一个迭代器,每个yield语句都表示一次暂停或中断。
  • yield break用于中断当前迭代,此时,自动生成的迭代器的MoveNext()会返回false。
  • yield return用于暂停当前函数,并返回一个值,返回的值可以在迭代器中的Current属性中获取。
  • 再次调用迭代器的MoveNext时,会自动从上一个yield return之后开始运行。

仅使用一个迭代函数:

 IEnumerable<int> MyRange(int start,int end){for (int i = start+1; i <= end; i++){yield return i;}}

测试:

var range = MyRange(1,5);
Console.WriteLine("new range");
range.Foreach(i =>
{Console.WriteLine("print : " + i);
});

new range
MyRangeIterator MoveNext : 1
print : 2
MyRangeIterator MoveNext : 2
print : 3
MyRangeIterator MoveNext : 3
print : 4
MyRangeIterator MoveNext : 4
print : 5
MyRangeIterator MoveNext : 5


http://www.mrgr.cn/news/349.html

相关文章:

  • 算法练习4:并查集/连通图 1:知识点梳理
  • 引领未来视界:OLED柔性屏在公司展厅公共显示栏的创新应用
  • Linux学习之路 -- 进程 -- 进程间通信 -- 管道通信
  • Apache Flink细粒度资源管理原理
  • 什么是光伏气象站——仁科测控
  • 定制化三防平板:满足个性化需求
  • vue3结合海康WEB开发包,开发web在线预览视频
  • 甘肃旅游服务平台代码--论文pf
  • SD三分钟入门!秋叶大佬24年8月最新的Stable Diffusion整合包V4.9.7来了~
  • CANoe入门学习
  • 聊天室项目测试报告
  • python 压力测试脚本
  • AC-DC应用中实现偏置电源的3种选择
  • RAG与LLM原理及实践(13)--- hybrid async search 使用及源码分析
  • 2024年电赛H题全开源
  • 华为OD机试-喊7的次数重排(JavaPythonC++)100%通过率,最新E卷题目
  • 浅谈Sql Server 索引
  • MyBatis
  • 登录方式(c语言)
  • Mysql笔记