C#设计模式(15)——迭代器模式
1.迭代器模式介绍
迭代器模式主要用于遍历聚合对象,将聚合对象的遍历行为分离出来,抽象为一个迭代器来负责。迭代器模式用的十分普遍,C#/JAVA等高级语言都对迭代器进行了封装用于遍历数组,集合,列表等,因为各种高级语言都对这种模式做了很好的封装,所以这种模式的使用价值远大于它的学习价值,MartinFlower甚至在网站上提出过撤销这个设计模式,所以这里不打算介绍迭代器模式的概念和原理,而是介绍C#中的迭代器模式应用:C#中的枚举器和迭代器。
2、枚举器和可枚举类型
先看一个简单的例子:
static void Main(string[] args)
{
int[] arr = { ,,,};
foreach (int item in arr)
{
Console.WriteLine("item's Value is :{0}",item);
}
Console.ReadKey();
}
为什么数组能够通过foreach遍历呢?原因是数组实现了IEnumerable接口,IEumerable接口中只有一个成员方法:GetEnumerator(),这个方法返回一个枚举器对象,这个枚举器就是迭代器模式中的迭代器。枚举器可以依次返回请求中数组中的元素,它知道元素的顺序并跟踪元素在序列中的位置,然后返回请求的当前项,我们可以通过GetEnumerator方法获取枚举器对象。那么什么是枚举器呢?实现IEnumerator接口的类型就是枚举器,该接口有三个成员:
current :获取当前位置元素
MoveNext() :把枚举器位置前进到下一项,返回bool,表示位置是否有效(如果没有下一项返回false)
Reset() :把位置重置为原始状态的位置(有索引是一般为-1)
我们重新实现上边例子的foreach操作:
static void Main(string[] args)
{
int[] arr = { ,,,};
//获取arr的枚举器
IEnumerator ie = arr.GetEnumerator();
while (ie.MoveNext())
{
int i = (int)ie.Current;
Console.WriteLine("item's value is:{0}",i);
}
Console.ReadKey();
}
知道了foreach内部是怎么运行的后,我们就可以自己实现一个可以用foreach遍历的类了:自定义的类要实现IEnumerable接口的GetEnumerator方法,这个方法返回一个枚举器(就是一个继承IEnumerator接口的类型),以遍历自定义颜色集合为例,代码如下:
class Program
{
static void Main(string[] args)
{
ColorList colors = new ColorList();
//foreach遍历自定义的类型
foreach (var item in colors)
{
Console.WriteLine(item);
} Console.ReadKey(); } /// <summary>
/// 自定义类 ColorList实现IEnumerable接口
/// </summary>
public class ColorList : IEnumerable
{
//实现GetEnumerator接口方法
public IEnumerator GetEnumerator()
{
return new ColorEnumrator(new string[]{ "red", "blue", "green", "pink" });
}
}
/// <summary>
/// 自定义枚举器
/// </summary>
public class ColorEnumrator : IEnumerator
{
string[] _colors;
//位置索引
private int _position = -;
//枚举器构造方法
public ColorEnumrator(string[] theColors)
{
_colors = new string[theColors.Length];
for (int i = ; i < theColors.Length; i++)
{
_colors[i] = theColors[i];
}
}
//获取当前项的值
public object Current
{
get
{
if (_position < || _position > _colors.Length)
{
throw new Exception("超过边界了!");
}
return _colors[_position];
}
}
//指向下一项
public bool MoveNext()
{
if (_position<_colors.Length-)
{
_position++;
return true;
}
return false;
}
//复位
public void Reset()
{
_position = -;
}
}
}
程序运行结果如下:
总结:可枚举类型是实现了IEnumerable接口的类,IEnumerable接口只有一个成员GetEnumerator方法,用于获取枚举器(实现IEnumerator接口的实例)。
3.迭代器
通过手动实现IEnumerable接口的IEnumerator方法我们已经可以实现自定义可枚举类型了,在C#2.0中提供了更简单的创建可枚举类型的方式:迭代器。我们使用迭代器时,不用我们自己去手动创建IEnumerator实例,编译器会自动帮我们生成IEnumerator内部的Current,MoveNext和Reset方法。使用迭代器上边的例子可以简化为:
class Program
{
static void Main(string[] args)
{
ColorList colors = new ColorList();
//foreach遍历自定义的ColorList类型
foreach (var item in colors)
{
Console.WriteLine(item);
}
Console.ReadKey(); } } /// <summary>
/// 自定义颜色集合,实现IEnumerable接口
/// </summary>
public class ColorList : IEnumerable
{
//实现GetEnumerator接口方法
public IEnumerator GetEnumerator()
{
string[] colors= { "red", "green", "blue", "pink" };
for (int i = ; i < colors.Length; i++)
{
//yield return的作用是指定下一项的内容
yield return colors[i];
} //想反向遍历时可以这样写
//for (int i = colors.Length-1; i >=0; i--)
//{
// yield return colors[i];
//}
}
}
程序运行结果和手动写Enumerator的例子一致,我们可以看出使用迭代器来生成可枚举类型要简单很多,这并不是创建迭代器的过程简单了,而是微软让编译器帮我们自动生成了IEnumerator中的current,MoveNext(),Reset()等内容。
C#设计模式(15)——迭代器模式的更多相关文章
- Python进阶:设计模式之迭代器模式
在软件开发领域中,人们经常会用到这一个概念——“设计模式”(design pattern),它是一种针对软件设计的共性问题而提出的解决方案.在一本圣经级的书籍<设计模式:可复用面向对象软件的基础 ...
- c++设计模式15 --组合模式
今天研究了一下设计模式15 组合模式 本人是菜鸟一枚,所以一开始完全不懂组合究竟是什么意思.先上图一张,树形结构图: 文档说,如果想做出这样的结构,通常考虑组合模式.那是为什么呢?现在让我们看一下组合 ...
- 乐在其中设计模式(C#) - 迭代器模式(Iterator Pattern)
原文:乐在其中设计模式(C#) - 迭代器模式(Iterator Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 迭代器模式(Iterator Pattern) 作者:weba ...
- 设计模式学习--迭代器模式(Iterator Pattern)和组合模式(Composite Pattern)
设计模式学习--迭代器模式(Iterator Pattern) 概述 ——————————————————————————————————————————————————— 迭代器模式提供一种方法顺序 ...
- js设计模式——4.迭代器模式
js设计模式——4.迭代器模式 代码演示 /*js设计模式——迭代器模式*/ class Iterator { constructor(container) { this.list = contain ...
- 实践GoF的设计模式:迭代器模式
摘要:迭代器模式主要用在访问对象集合的场景,能够向客户端隐藏集合的实现细节. 本文分享自华为云社区<[Go实现]实践GoF的23种设计模式:迭代器模式>,作者:元闰子. 简介 有时会遇到这 ...
- C#设计模式学习笔记:(15)迭代器模式
本笔记摘抄自:https://www.cnblogs.com/PatrickLiu/p/7903617.html,记录一下学习过程以备后续查用. 一.引言 今天我们要讲行为型设计模式的第三个模式--迭 ...
- 设计模式之迭代器模式(Iterator)摘录
23种GOF设计模式一般分为三大类:创建型模式.结构型模式.行为模式. 创建型模式抽象了实例化过程,它们帮助一个系统独立于怎样创建.组合和表示它的那些对象.一个类创建型模式使用继承改变被实例化的类,而 ...
- 设计模式(8) - 迭代器模式(iterator)- 实现ArrayList和linkedList的迭代器
上周六就開始写这篇博客,之后一直耽误了.到前天才開始写.今天醒的早,就把这部分整理一下. 本文内容參考易学设计模式和马士兵的迭代器模式的视频. 了解迭代器模式一个作用就是让你在使用 迭代器遍历集合类的 ...
- Head First 设计模式 --9 迭代器模式 组合模式
迭代器模式:提供一种方法书序访问一个聚合对象中的各个元素,而又不暴露其内部的表示. 用到的设计原则:1.封装变化2.多用组合,少用继承|3.针对接口编程,不针对实现编程4.松耦合5.对扩展开放,对修改 ...
随机推荐
- 8 commands to check cpu information on Linux
https://www.binarytides.com/linux-cpu-information/
- react + dva + ant架构后台管理系统(一)
一.什么是dva dva是蚂蚁金服推出的一个单页应用框架,对 redux, react-router, redux-saga进行了上层封装,没有引入新的概念,但是极大的程度上提升了开发效率: 二.安装 ...
- Bootstrap学习目录
前面的话 Bootstrap与CSS的关系,类似于javascript与jQuery的关系,原理与应用的关系.只是jQuery不再火爆,而Bootstrap依然火热,它在github有着超过100万的 ...
- jenkins--svn+添加钩子去触发jenkins的job工作
找到svn钩子脚本 post-commit: 添加一个接口: /usr/bin/curl http://admin:admin@x.x.x.x:8080/job/svn/buildWithParame ...
- day24 包
# 把解决一类问题的模块会被放在一个文件夹里面,即包 # import os # os.makedirs('glance/api') # os.makedirs('glance/cmd') # os. ...
- MT【231】棋子方法数
设有5枚无区别的棋子放在如图$5*5$的棋盘的小方格中,放棋子的规则是每行每列放且仅放一个棋子,同时,不允许放在黑方格内,则共有______ 方法. 答案:5的错排数44.第一行的数不放第二列(相当于 ...
- 06 自学Aruba之win7系统802.1x认证网卡设置指导
点击返回:自学Aruba之路 06 自学Aruba之win7系统802.1x认证网卡设置指导 步骤1.在桌面任务栏找到“打开网络和共享中心”,点击进入: 步骤2.点击“管理无线网络”,进入无线网络配置 ...
- Intent 传递数据
使用INtent 在页面之间跳转,数据传递是必须的,我们可以直接在intent 对象上放置基本数据类型的数据,也可以放置字符串和其他数据类型数据.对于其他数据类型,实现了Parcelable 或Ser ...
- SharePoint 2013 Newsfeed 没有出现的解决方法
按照这个guide配置mysite: http://technet.microsoft.com/en-us/library/ee624362(v=office.15).aspx 但是newsfeed页 ...
- luogu4182 [USACO18JAN] Lifeguards P (单调队列优化dp)
显然可以先把被覆盖掉的区间去掉,然后排个序,左.右端点就都是单调的 设f[i][j]表示前i个区间中删掉j个,而且钦定i不能删的最大覆盖长度 (如果不钦定,就要有一个删掉的状态,那我无法确定前面的到底 ...