news 2026/6/4 22:30:32

17. 迭代器模式(Iterator Pattern)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
17. 迭代器模式(Iterator Pattern)

17. 迭代器模式(Iterator Pattern)

分类: 行为型模式
热门度: ★★★★★
难度: ★★☆☆☆


📖 概念

迭代器模式提供一种方法顺序访问聚合对象中的各个元素,而不暴露其内部表示。C# 中IEnumerable<T>IEnumerator<T>就是迭代器模式的标准实现。

🎯 意图

提供统一的遍历接口,隐藏集合的内部结构,支持多种遍历方式。

🔑 关键角色

角色说明
IIterator(迭代器接口)定义 HasNext()、Next() 等遍历方法
ConcreteIterator(具体迭代器)实现遍历逻辑,维护当前位置
IAggregate(聚合接口)定义创建迭代器的方法
ConcreteAggregate(具体聚合)实现聚合接口,提供数据源

⚠️ 注意事项

  • C# 内置了IEnumerable<T>/IEnumerator<T>,通常直接实现即可
  • 注意迭代过程中的集合修改问题(InvalidOperationException
  • 可用yield return简化迭代器实现

🔄 实现流程

1. 实现 IEnumerable<T> 接口(GetEnumerator 方法) 2. 实现 IEnumerator<T> 接口(MoveNext、Current、Reset) 3. 或使用 yield return 语法糖自动实现 4. 客户端通过 foreach 遍历

💡 常见使用场景

场景1: 自定义集合遍历

// 自定义集合publicclassBookCollection:IEnumerable<Book>{privateList<Book>_books=new();publicvoidAdd(Bookbook)=>_books.Add(book);publicIEnumerator<Book>GetEnumerator()=>newBookEnumerator(_books);System.Collections.IEnumeratorSystem.Collections.IEnumerable.GetEnumerator()=>GetEnumerator();}publicclassBook{publicstringTitle{get;set;}publicstringAuthor{get;set;}publicBook(stringtitle,stringauthor){Title=title;Author=author;}}// 自定义迭代器publicclassBookEnumerator:IEnumerator<Book>{privateList<Book>_books;privateint_position=-1;publicBookEnumerator(List<Book>books){_books=books;}publicBookCurrent=>_books[_position];objectSystem.Collections.IEnumerator.Current=>Current;publicboolMoveNext()=>++_position<_books.Count;publicvoidReset()=>_position=-1;publicvoidDispose(){}}// 使用varcollection=newBookCollection();collection.Add(newBook("设计模式","GoF"));collection.Add(newBook("重构","Martin Fowler"));collection.Add(newBook("代码整洁之道","Robert C. Martin"));foreach(varbookincollection)Console.WriteLine($"{book.Title}-{book.Author}");

场景2: 二叉树中序遍历迭代器

publicclassTreeNode<T>{publicTValue{get;set;}publicTreeNode<T>Left{get;set;}publicTreeNode<T>Right{get;set;}publicTreeNode(Tvalue){Value=value;}}publicclassInOrderEnumerator<T>:IEnumerator<T>{privateStack<TreeNode<T>>_stack=new();privateTreeNode<T>_current;privateTreeNode<T>_root;publicInOrderEnumerator(TreeNode<T>root){_root=root;_current=root;PushLeft(root);}privatevoidPushLeft(TreeNode<T>node){while(node!=null){_stack.Push(node);node=node.Left;}}publicTCurrent=>_current.Value;objectSystem.Collections.IEnumerator.Current=>Current;publicboolMoveNext(){if(_stack.Count==0)returnfalse;_current=_stack.Pop();if(_current.Right!=null)PushLeft(_current.Right);returntrue;}publicvoidReset(){_stack.Clear();PushLeft(_root);}publicvoidDispose(){}}publicclassBinaryTree<T>:IEnumerable<T>{publicTreeNode<T>Root{get;set;}publicBinaryTree(TreeNode<T>root){Root=root;}publicIEnumerator<T>GetEnumerator()=>newInOrderEnumerator<T>(Root);System.Collections.IEnumeratorSystem.Collections.IEnumerable.GetEnumerator()=>GetEnumerator();}// 使用vartree=newBinaryTree<int>(newTreeNode<int>(4){Left=newTreeNode<int>(2){Left=newTreeNode<int>(1),Right=newTreeNode<int>(3)},Right=newTreeNode<int>(6){Left=newTreeNode<int>(5),Right=newTreeNode<int>(7)}});foreach(varvalintree)Console.Write($"{val}");// 1 2 3 4 5 6 7

场景3: 使用 yield return 简化实现

publicclassRange{privateint_start,_end,_step;publicRange(intstart,intend,intstep=1){_start=start;_end=end;_step=step;}// 使用 yield return 自动生成迭代器publicIEnumerable<int>GetNumbers(){for(inti=_start;i<_end;i+=_step)yieldreturni;}// 斐波那契无限序列publicstaticIEnumerable<int>Fibonacci(){inta=0,b=1;while(true){yieldreturna;(a,b)=(b,a+b);}}// 按条件过滤publicIEnumerable<T>Filter<T>(IEnumerable<T>source,Func<T,bool>predicate){foreach(variteminsource)if(predicate(item))yieldreturnitem;}}// 使用foreach(varninnewRange(1,10,2).GetNumbers())Console.Write($"{n}");// 1 3 5 7 9foreach(varfibinRange.Fibonacci().Take(10))Console.Write($"{fib}");// 0 1 1 2 3 5 8 13 21 34

✅ 优点

  • 支持多种遍历方式
  • 简化聚合类,不需要暴露内部结构
  • 可以同时对同一聚合进行多次遍历

❌ 缺点

  • 增加了类的数量
  • 遍历比直接访问元素略慢

📊 与其他模式对比

模式区别
组合模式组合模式管理树结构,迭代器模式遍历元素
访问者模式访问者在元素上执行操作,迭代器只负责遍历
备忘录模式备忘录保存状态,迭代器遍历集合
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/4 22:29:34

高考毕业同学录设计图片素材 轻松搞定毕业季各类设计需求

高考毕业季同学录留言本设计素材分享 这次整理了一批高考毕业主题的同学录留言本设计素材&#xff0c;融入了纸飞机、千纸鹤这些自带青春滤镜的小元素&#xff0c;清晰度够高&#xff0c;各类毕业相关的创作基本都能用 清新风的毕业季长屏插画&#xff0c;用来做校园公众号…

作者头像 李华
网站建设 2026/6/4 22:23:08

【元器件专题】MOS管上下桥设计详解(死区时间)

双MOS构造的上下桥互补电路&#xff0c;如果设计不合理会造成上下管同时导通的风险。S1为上桥GS驱动信号&#xff0c;S2为下桥驱动信号&#xff0c;假设驱动信号逻辑如下&#xff1a;理想情况下&#xff0c;S1为低电平时&#xff0c;S2为高电平时&#xff0c;那就是上桥关断&am…

作者头像 李华
网站建设 2026/6/4 22:22:24

ARM Cortex-M 寄存器全家桶:从“三大神器”到完整图谱

&#x1f525;作者简介&#xff1a; 一个平凡而乐于分享的小比特&#xff0c;中南民族大学通信工程专业研究生&#xff0c;研究方向无线联邦学习 &#x1f3ac;擅长领域&#xff1a;驱动开发&#xff0c;嵌入式软件开发&#xff0c;BSP开发 ❄️作者主页&#xff1a;一个平凡而…

作者头像 李华
网站建设 2026/6/4 22:18:41

LinkSwift:5分钟掌握网盘直链解析终极方案,告别限速烦恼

LinkSwift&#xff1a;5分钟掌握网盘直链解析终极方案&#xff0c;告别限速烦恼 【免费下载链接】Online-disk-direct-link-download-assistant 一个基于 JavaScript 的网盘文件下载地址获取工具。基于【网盘直链下载助手】修改 &#xff0c;支持 百度网盘 / 阿里云盘 / 中国移…

作者头像 李华