博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C#设计模式(15)——迭代器模式
阅读量:5304 次
发布时间:2019-06-14

本文共 4592 字,大约阅读时间需要 15 分钟。

出处:

 

阅读目录

 


1.迭代器模式介绍

  迭代器模式主要用于遍历聚合对象,将聚合对象的遍历行为分离出来,抽象为一个迭代器来负责。迭代器模式用的十分普遍,C#/JAVA等高级语言都对迭代器进行了封装用于遍历数组,集合,列表等,因为各种高级语言都对这种模式做了很好的封装,所以这种模式的使用价值远大于它的学习价值,MartinFlower甚至在网站上提出过撤销这个设计模式,所以这里不打算介绍迭代器模式的概念和原理,而是介绍C#中的迭代器模式应用:C#中的枚举器和迭代器。

2、枚举器和可枚举类型

先看一个简单的例子:

1     static void Main(string[] args)2         {3             int[] arr = { 2,3,5,8};4             foreach (int item in arr)5             {6                 Console.WriteLine("item's Value is :{0}",item);7             }8             Console.ReadKey();9         }

  为什么数组能够通过foreach遍历呢?原因是数组实现了IEnumerable接口,IEumerable接口中只有一个成员方法:GetEnumerator(),这个方法返回一个枚举器对象,这个枚举器就是迭代器模式中的迭代器。枚举器可以依次返回请求中数组中的元素,它知道元素的顺序并跟踪元素在序列中的位置,然后返回请求的当前项,我们可以通过GetEnumerator方法获取枚举器对象。那么什么是枚举器呢?实现IEnumerator接口的类型就是枚举器,该接口有三个成员:

   current :获取当前位置元素

   MoveNext() :把枚举器位置前进到下一项,返回bool,表示位置是否有效(如果没有下一项返回false)

   Reset() :把位置重置为原始状态的位置(有索引是一般为-1)

我们重新实现上边例子的foreach操作:

1      static void Main(string[] args) 2         { 3             int[] arr = { 2,3,5,8}; 4             //获取arr的枚举器 5             IEnumerator ie = arr.GetEnumerator(); 6             while (ie.MoveNext()) 7             { 8                 int i = (int)ie.Current; 9                 Console.WriteLine("item's value is:{0}",i);10             }11             Console.ReadKey();12         }

  知道了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();        }                ///         /// 自定义类 ColorList实现IEnumerable接口        ///         public class ColorList : IEnumerable        {            //实现GetEnumerator接口方法            public IEnumerator GetEnumerator()            {                return new ColorEnumrator(new string[]{ "red", "blue", "green", "pink" });            }        }        ///         /// 自定义枚举器        ///         public class ColorEnumrator : IEnumerator        {            string[] _colors;            //位置索引            private int _position = -1;            //枚举器构造方法            public ColorEnumrator(string[] theColors)            {                _colors = new string[theColors.Length];                for (int i = 0; i < theColors.Length; i++)                {                    _colors[i] = theColors[i];                }            }            //获取当前项的值            public object Current            {                get                {                    if (_position < 0 || _position > _colors.Length)                    {                        throw new Exception("超过边界了!");                    }                    return _colors[_position];                }            }            //指向下一项            public bool MoveNext()            {                if (_position<_colors.Length-1)                {                    _position++;                    return true;                }                return false;            }            //复位            public void Reset()            {                _position = -1;            }        }    }

程序运行结果如下:

总结:可枚举类型是实现了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();                   }          }        ///     /// 自定义颜色集合,实现IEnumerable接口    ///     public class ColorList : IEnumerable    {        //实现GetEnumerator接口方法        public IEnumerator GetEnumerator()        {            string[] colors= { "red", "green", "blue", "pink" };            for (int i = 0; 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()等内容。

转载于:https://www.cnblogs.com/frank0812/p/11301840.html

你可能感兴趣的文章
Python-S9-Day127-Scrapy爬虫框架2
查看>>
SecureCRT的使用方法和技巧(详细使用教程)
查看>>
右侧导航栏(动态添加数据到list)
查看>>
81、iOS本地推送与远程推送详解
查看>>
虚拟DOM
查看>>
自建数据源(RSO2)、及数据源增强
查看>>
关于View控件中的Context选择
查看>>
2018icpc徐州OnlineA Hard to prepare
查看>>
Spark的启动进程详解
查看>>
使用命令创建数据库和表
查看>>
数据库的高级查询
查看>>
机器视觉:SSD Single Shot MultiBox Detector
查看>>
201521123044 《Java程序设计》第1周学习总结
查看>>
MIT Scheme 的基本使用
查看>>
程序员的“机械同感”
查看>>
在16aspx.com上下了一个简单商品房销售系统源码,怎么修改它的默认登录名和密码...
查看>>
c++回调函数
查看>>
linux下Rtree的安装
查看>>
【Java】 剑指offer(53-2) 0到n-1中缺失的数字
查看>>
Delphi中ListView类的用法
查看>>