转:https://blog.csdn.net/wang371756299/article/details/8197075
摘要: IEnumerable接口是实现foreach循环的一个重要的接口,像数组、集合等之所以可以用foreach循环遍历其中的每个元素便是因为他们都实现了IEnumerable接口而,那么这个接口到底是如何运行的呢,通过下面一个例子可以得到 ...

IEnumerable接口是实现foreach循环的一个重要的接口,像数组、集合等之所以可以用foreach循环遍历其中的每个元素便是因为他们都实现了IEnumerable接口而,那么这个接口到底是如何运行的呢,通过下面一个例子可以得到一些启发。

定义一个这样简单的类:

01.public class Person
02. {
03. private string[] names= new string[] { "A", "B", "C" };
04. }

由于names属性是私有属性,所以无法通过Person类的对象对其进行访问,也就无法对其遍历,可以让Person类实现IEnumerable接口来对其进行遍历,实现接口后的类如下:

01.public class Person : IEnumerable
02. {
03. private string[] names= new string[] { "A", "B", "C" };
04.
05. public IEnumerator GetEnumerator()
06. {
07.
08. }
09. }

可以看到实现了IEnumerable接口后Person类里面必须实现一个GetEnumerator函数,该函数返回的是一个类型为IEnumerator 的对象,于是我们再写一个类继承自IEnumerator 接口:

01.public class PersonEnumerator : IEnumerator
02. {
03. //定义一个字符串数组
04. private string[] _names;
05.
06. //遍历时的索引
07. private int index = -1;
08.
09. //构造函数,带一个字符串数组的参数
10. public PersonEnumerator(string[] temp)
11. {
12. _names = temp;
13. }
14.
15. //返回当前索引指向的names数组中的元素
16. public object Current
17. {
18. get { return _names[index]; }
19. }
20.
21. //索引,判断是否遍历完成
22. public bool MoveNext()
23. {
24. index++;
25. if (index < _names.Length)
26. {
27. return true;
28. }
29. else
30. return false;
31. }
32.
33. //重置索引的值,以便下一次遍历
34. public void Reset()
35. {
36. index = -1;
37. }
38. }

然后对GetEnumerator函数稍加修改就大功告成了,如下:

01.public class Person : IEnumerable
02. {
03. private string[] names = new string[] { "A", "B", "C" };
04.
05. public IEnumerator GetEnumerator()
06. {
07. //调用PersonEnumerator类的构造函数,并Person类中的names数组传递过去
08. return new PersonEnumerator(names);
09. }
10. }

然后就可以用foreach对Person类的对象进行遍历了,如下:

01.static void Main(string[] args)
02. {
03. Person p1 = new Person();
04. foreach (string item in p1)
05. {
06. Console.WriteLine(item);
07. }
08. Console.ReadKey();
09. }

我们也可以用如下方法对names数组进行遍历:

01.static void Main(string[] args)
02. {
03. Person p1 = new Person();
04. IEnumerator rator = p1.GetEnumerator();
05. while (rator.MoveNext())
06. {
07. Console.WriteLine(rator.Current);
08. }
09. Console.ReadKey();
10. }

最新文章

  1. JavaScrict中的断言调试
  2. android:使用Messenger进行进程间通信(二)
  3. ion-header-bar
  4. 39. 求分数序列前N项和
  5. Singelton单例模式
  6. Java Web高性能开发(二)
  7. Jquery扩展-手把手带你体验
  8. 终极秘籍教你怎么找回被盗iPhone 查询ICCID
  9. 数学(欧拉函数):UVAOJ 11426 GCD - Extreme (II)
  10. 让程序只运行一个实例(Delphi篇)(三种方法,其中使用全局原子的方法比较有意思)
  11. PHP用CURL或fsockopen伪造IP和来路(referer)
  12. [2012-06-21]结合find的awk
  13. 认识浏览器请求头User-Agent
  14. 关于定时器setTimeout()方法的实践--巧解bug
  15. [Swift]在Swift项目中创建桥接头文件,Swift文件和Objective-C文件相互调用
  16. Sublime Text3 C++ 设置
  17. 转自: linux svn命令行无法拉取中文名称的文件
  18. django rest_framework 分页出现报错
  19. 2-4 完整Todolist案例
  20. Asp.Net Core 2.0 项目实战(3)NCMVC角色权限管理前端UI预览及下载

热门文章

  1. To use the new Server Discover and Monitoring engine, pass option { useUnifiedTopology: true } to the MongoClient constructor.
  2. RaspberryPi 3b+ 安装OpenWrt教程
  3. k8s~部署EFK框架
  4. 移动端 location.href 无法成功跳转页面
  5. CSS中的圣杯布局与双飞翼布局
  6. mysql实现远程登录
  7. Python 编程入门(2):复杂数据类型(列表,字典)
  8. vue中允许你继续使用swiper的组件 vue-awesome-swiper---切图网
  9. Anaconda 包管理与环境管理
  10. 8maven配置多个项目之间的依赖