上一篇文章为自定义类实现了foreach的功能,但实现过程中要实现IEnumerator接口(包括MoveNext、Reset函数和Current属性)以便GetEnumerator函数能获取枚举数,有点复杂,有点繁琐。

已经知道:主要一个类实现了GetEnumerator函数就能foreach,而实现IEnumerator接口只是实现 GetEnumerator函数的其中一个办法,也就说还有其他办法实现GetEnumerator函数了?是的,C#2.0为我们提供了一种很简单的方 法来实现GetEnumerator函数,那就是使用迭代器!(还记得吧,C#里的迭代器和C++里的是不同的)

下面是来自MSDN的解说:

迭代器概述

  • 迭代器是可以返回相同类型的值的有序序列的一段代码。

  • 迭代器可用作方法、运算符或 get 访问器的代码体。

  • 迭代器代码使用 yield return 语句依次返回每个元素。yield break 将终止迭代。有关更多信息,请参见 yield。

  • 可以在类中实现多个迭代器。每个迭代器都必须像任何类成员一样有唯一的名称,并且可以在 foreach 语句中被客户端代码调用,如下所示:foreach(int x in SampleClass.Iterator2){}

  • 迭代器的返回类型必须为 IEnumerable、IEnumerator、IEnumerable<T> 或 IEnumerator<T>。

yield 关键字用于指定返回的值。到达 yield return 语句时,会保存当前位置。下次调用迭代器时将从此位置重新开始执行。

第一部分:使用默认迭代器实现获取枚举数

1、定义Person类

View Code

 1     public class Person 2     { 3         public string Name; 4         public int Age; 5  6         public Person(string name, int age) 7         { 8             Name = name; 9             Age = age;10         }11 12         public override string ToString()13         {14             return "Name:  " + Name + "\tAge:  " + Age;15         }16     }

2、定义PeopleEnum1类,里面实现了GetEnumerator函数(也就是迭代器了,这是默认的迭代器),但实现的过程相对于上一篇文 章里介绍的实现过程要简单很多,这就是yield的功效。yield的实现原理这里就不详说了,可以概括为:GetEnumerator函数里的迭代块把 IEnumerator接口的MoveNext、Reset方法和Current属性封装了,但本质没变,只是我们使用起来更方便了。

 1     public class PeopleEnum1 2     { 3         private Person[] _perple; 4  5         //构造函数 6         public PeopleEnum1(Person[] list) 7         { 8             _perple = new  Person[list.Length]; 9             for (int i = 0; i < list.Length; i++)10             {11                 _perple[i] = list[i];12             }13         }14 15         public IEnumerator GetEnumerator()16         {17             for (int i = 0; i < _perple.Length; i++)18             {19                 yield return _perple[i];20             }21         }22 23     }

3、主函数代码

View Code

 1     class Program 2     { 3         static void Main(string[] args) 4         { 5             Person[] persons = new Person[]  6             { 7                 new Person("aaa", 20), 8                 new Person("bbb", 21), 9                 new Person("ccc", 22)10             };11 12             PeopleEnum1 peopleEnum = new PeopleEnum1(persons);13 14             foreach (var item in peopleEnum)15             {16                 System.Console.WriteLine(item);17 18             }19 20             System.Console.ReadKey();21         }22     }

运行,成功,嘿嘿

第二部分:自定义迭代器

第一部分用默认迭代器GetEnumerator 实现了类的foreach,我们也可以定义自己的迭代器来获取自己想要的枚举数。比较说,我想列举出类中未成年人的信息,默认的迭代器无能为力,该怎么实现自定义的迭代器呢?

1、为PeopleEnum1类添加一个迭代器 GetChildren ,在这里,这个迭代器是一个属性,也可以定义为函数。对于类中的元素,只有Age 小于18的元素才 yield return ,其他的不要。

View Code

2、主函数代码

View Code

输出结果:

可以看到,自定义的迭代器 GetChildren 成功foreach了。

注意:默认迭代器 GetEnumerator 的返回类型是 IEnumerator ,并且在使用foreach时 in 后面直接是类名。而自定义迭代器 GetChildren 的返回类型是 IEnumerable,并且在使用foreach时 in 后面是 PeopleEnum.GetChildren(类名.迭代器名)。好像,好像是规定这样子的,原理是什么还不清楚。

引用自 :http://www.cnblogs.com/zouzf/archive/2012/02/22/2362954.html

转载于:https://www.cnblogs.com/zhangchenliang/archive/2012/08/19/2646781.html

C#学习之用迭代器实现枚举器相关推荐

  1. 一文详解枚举器和迭代器!

    作者 | 喵叔 责编 | 胡巍巍 出品 | 程序人生(ID:coder_life) 今天来讲解一下开发人员会用但不理解的C#中的知识,这篇文章我们讲解一下枚举器与迭代器的知识. 枚举器 什么是枚举器? ...

  2. C#图解教程 第十八章 枚举器和迭代器

    枚举器和迭代器 枚举器和可枚举类型 第12章中,我们看到可以用foreach语句遍历数组.在本章,我们会进一步探讨数组,来看看为什么它们可以被foreach语句处理.我们还会研究如何使用迭代器为用户自 ...

  3. C# 入门(14) 枚举器(enumerator)和迭代器(iterator)

    C#的枚举器和迭代器 参考书籍: <C#图解教程> 枚举器一般用来foreach的,而迭代器在Unity中常用来当协程(Coroutine)用. 枚举器 IEnumerator接口 实现I ...

  4. C# IEnumerator枚举器

    1.对象只要一个类型实现了IEnumerable接口就能遍历 2.IEnumerator是枚举器,一个接口类,实现MoveNext->Current->Reset 3.yield关键字是一 ...

  5. 迭代器、装饰器、软件开发规范

    本节内容 迭代器&生成器 装饰器 Json & pickle 数据序列化 软件目录结构规范 作业:ATM项目开发 1.列表生成式,迭代器&生成器 列表生成式 孩子,我现在有个需 ...

  6. Python之迭代器、装饰器、软件开发规范

    本节内容 迭代器&生成器 装饰器 Json & pickle 数据序列化 软件目录结构规范 作业:ATM项目开发 1.列表生成式,迭代器&生成器 列表生成式 孩子,我现在有个需 ...

  7. 迭代器/生成器/装饰器 /Json pickle 数据序列化

    本节内容 迭代器&生成器 装饰器 Json & pickle 数据序列化 软件目录结构规范 作业:ATM项目开发 1.列表生成式,迭代器&生成器 列表生成式 孩子,我现在有个需 ...

  8. Day4 - Python基础4 迭代器、装饰器、软件开发规范

    Python之路,Day4 - Python基础4 (new版) 本节内容 迭代器&生成器 装饰器 Json & pickle 数据序列化 软件目录结构规范 作业:ATM项目开发 1. ...

  9. Python基础 day4 迭代器生成器 装饰器 Json pickle 数据序列化 软件目录结构规范 作业:ATM项目开发...

    本节内容 迭代器&生成器 装饰器 Json & pickle 数据序列化 软件目录结构规范 作业:ATM项目开发 列表生成器 1.列表生成式,迭代器&生成器 列表生成式 孩子, ...

最新文章

  1. ActiveMQ消息存储持久化
  2. org.openqa.selenium.StaleElementReferenceException
  3. 漂亮的HTML表格 - ebirdfighter的日志 - 网易博客
  4. Evaluation of Deep Learning Toolkits
  5. 使用fyne绘制一个交通图标
  6. Spring整合了CXF的一个applicationContext.xml的配置文件
  7. ASP.NET操作Excel(终极方法NPOI)
  8. 移动端ios中click点击失效
  9. php get验证,PHP+Ajax简单get验证操作示例
  10. android app打开流程_app开发模式的应用
  11. 剑指offer之连续子数组的最大和
  12. python机器学习库xgboost使用调参
  13. 【语音加密】基于matlab混沌+AES语音加密解密【含Matlab源码 1593期】
  14. Linux拷贝分区内容,dd复制分区后目标分区的大小变成原分区了
  15. 爬虫——xpath爬取图片
  16. 如何修改ftp服务器密码,如何修改FTP密码
  17. 共模干扰和差模干扰的处理方式
  18. noip2017广东提高组复赛成绩
  19. Client<unknown> disconnected, not authorised
  20. JAVA检验密码复杂度+随机生成6位密码

热门文章

  1. c++错误之map的find()返回值类型
  2. 100的阶乘c语言代码,求10000的阶乘(c语言代码实现)
  3. [攻防世界 pwn]——Mary_Morton
  4. 关于定时执行任务的解决方法,PendingIntent alarm braocastRecevier等等
  5. 新Hibernate SessionFactory().getCurrentSession()猫腻
  6. Silverlight4中用net.tcp双工方式进行通信
  7. SCA (Service Component Architecture)
  8. Hibernate 实体关联关系映射----总结
  9. 贞子的在日本历史出现过的轨迹
  10. python库(包)查找网站