IEnumerable 只有一个方法:IEnumerator GetEnumerator(). INumerable 是集合应该实现的一个接口,这样,就能用 foreach 来遍历这个集合。
IEnumerator 有Current属性,MoveNext(), Reset()两个方法。
 
当 foreach 使用到一个 IEnumerable 的集合上的时候,遍历是这样开始的:
1. 调用 GetEnumerator() 得到一个 IEnumerator 的对象。
2. 调用 MoveNext();
3. 使用 其中一个对象。
4. 重复2和3, 直到 MoveNext()返回 false(没有下一个啦).
 
由此可见
1. GetEnumerator() 返回的对象在最开始的时候,指针是放在第一个对象之前的,Reset()之后也是这样。
2. 为了使用 foreach, 实现 IEnumerable 不是必须的,只是一个 best practice 而已。
 
下面我们来看微软提供的一个例子:

  1. using System;
  2. using System.Collections;
  3.  
  4. // Simple business object.
  5. public class Person
  6. {
  7. public Person(string fName, string lName)
  8. {
  9. this.firstName = fName;
  10. this.lastName = lName;
  11. }
  12.  
  13. public string firstName;
  14. public string lastName;
  15. }
  16.  
  17. // Collection of Person objects. This class
  18. // implements IEnumerable so that it can be used
  19. // with ForEach syntax.
  20. public class People : IEnumerable
  21. {
  22. private Person[] _people;
  23. public People(Person[] pArray)
  24. {
  25. _people = new Person[pArray.Length];
  26.  
  27. for (int i = 0; i < pArray.Length; i++)
  28. {
  29. _people[i] = pArray[i];
  30. }
  31. }
  32.  
  33. // Implementation for the GetEnumerator method.
  34. IEnumerator IEnumerable.GetEnumerator()
  35. {
  36. return (IEnumerator) GetEnumerator();
  37. }
  38.  
  39. public PeopleEnum GetEnumerator()
  40. {
  41. return new PeopleEnum(_people);
  42. }
  43. }
  44.  
  45. // When you implement IEnumerable, you must also implement IEnumerator.
  46. public class PeopleEnum : IEnumerator
  47. {
  48. public Person[] _people;
  49.  
  50. // Enumerators are positioned before the first element
  51. // until the first MoveNext() call.
  52. int position = -1;
  53.  
  54. public PeopleEnum(Person[] list)
  55. {
  56. _people = list;
  57. }
  58.  
  59. public bool MoveNext()
  60. {
  61. position++;
  62. return (position < _people.Length);
  63. }
  64.  
  65. public void Reset()
  66. {
  67. position = -1;
  68. }
  69.  
  70. object IEnumerator.Current
  71. {
  72. get
  73. {
  74. return Current;
  75. }
  76. }
  77.  
  78. public Person Current
  79. {
  80. get
  81. {
  82. try
  83. {
  84. return _people[position];
  85. }
  86. catch (IndexOutOfRangeException)
  87. {
  88. throw new InvalidOperationException();
  89. }
  90. }
  91. }
  92. }
  93.  
  94. class App
  95. {
  96. static void Main()
  97. {
  98. Person[] peopleArray = new Person[3]
  99. {
  100. new Person("John", "Smith"),
  101. new Person("Jim", "Johnson"),
  102. new Person("Sue", "Rabon"),
  103. };
  104.  
  105. People peopleList = new People(peopleArray);
  106. foreach (Person p in peopleList)
  107. Console.WriteLine(p.firstName + " " + p.lastName);
  108.  
  109. }
  110. }
  111.  
  112. /* This code produces output similar to the following:
  113. *
  114. * John Smith
  115. * Jim Johnson
  116. * Sue Rabon
  117. *
  118. */

  

IEnumerable & IEnumerator的更多相关文章

  1. C# ~ 从 IEnumerable / IEnumerator 到 IEnumerable<T> / IEnumerator<T> 到 yield

    IEnumerable / IEnumerator 首先,IEnumerable / IEnumerator 接口定义如下: public interface IEnumerable /// 可枚举接 ...

  2. IEnumerable, IEnumerator接口

    IEnumerable接口 // Exposes the enumerator, which supports a simple iteration over a non-generic collec ...

  3. ICollection IEnumerable/IEnumerator IDictionaryEnumerator yield

    Enumerable和IEnumerator接口是.NET中非常重要的接口,二者区别: 1. IEnumerable是个声明式的接口,声明实现该接口的类就是“可迭代的enumerable”,但并没用说 ...

  4. c#yield,IEnumerable,IEnumerator

    foreach 在编译成IL后,实际代码如下: 即:foreach实际上是先调用可枚举对象的GetEnumerator方法,得到一个Enumerator对象,然后对Enumerator进行while循 ...

  5. 【Unity|C#】基础篇(20)——枚举器与迭代器(IEnumerable/IEnumerator)

    [学习资料] <C#图解教程>(第18章):https://www.cnblogs.com/moonache/p/7687551.html 电子书下载:https://pan.baidu. ...

  6. IEnumerable和IEnumerator

    概述 IEnumerable和IEnumerator接口存在的意义:用来实现迭代的功能! public interface IEnumerable { IEnumerator GetEnumerato ...

  7. IEnumerable和IEnumerator 详解 (转)

    原文链接:http://blog.csdn.net/byondocean/article/details/6871881 参考链接:http://www.cnblogs.com/hsapphire/a ...

  8. IEnumerator/IEnumerable接口

    IEnumberator函数成员 Current返回序列中当前位置项的 属性 只读属性 返回object类型 MoveNext把枚举器位置前进到集合中下一项的方法 新位置有效返回true,否则fals ...

  9. 转载IEnumerable与IEnumerator区别

    public interface IEnumerable {     IEnumerator GetEnumerator(); }   public interface IEnumerator {   ...

随机推荐

  1. VisualSVN 5.1.7破译License Key

    前面手敲一些简要的软件说明:visualSVN server大家都不陌生,服务器上的版本控制系统,一般配套Tortoisesvn(小乌龟)使用.本次介绍的这个visualsvn属于VisualStud ...

  2. redis 对象

    redis通过前面几篇的数据结构构键了一个对象系统,这个对象系统包含了字符串对象,列表对象,哈希对象,集合对象,有序集合对象 每一个对象都是一个redisobject typedef struct r ...

  3. workerman例子无法工作

    现象 workerman已经正常启动,但是按照官网写的例子或者下载的demo无法工作,例如页面打不开,socket连接失败等 解决方法 一般这种workerman启动没报错,但是无法打开页面或者无法连 ...

  4. strval

    将变量转成字符串类型. 语法: string strval(mixed var); 返回值: 字符串 函数种类: PHP 系统功能   内容说明 本函数可将数组及类之外的变量类型转换成字符串类型.   ...

  5. php对数组中的键与值进行合并处理

    $res=array(); $re=array_count_values($month); foreach( $re as $k=>$v){ $arr['month_name'] = strva ...

  6. 给linux虚拟机添加Samba用户

    Window系统连上我们的开发机Linux,自然需要在Samba里添加一个新用户. linux-06bq:/usr/local/services/samba/bin # ./smbpasswd -a  ...

  7. Example015实现html中checkbox的全选和反选(2)

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  8. 第二章(jQuery选择器)

    2.1jQuery选择器是什么 1.CSS选择器 选择器 示例 选择器 示例 标签选择器 a{ } p{ } ul{ } ID选择器 #ID{ } 类选择器 .class{ } 群组选择器 td,p, ...

  9. Egret的项目结构

    这是我新建的一个Egret EUI项目 .wing文件夹是项目的配置文件 bin-debug 文件夹,项目编译和运行的debug目录 libs 文件夹,存放库文件,包括 Egret 核心库,其他扩展库 ...

  10. poj 1948 Triangular Pastures 小结

    Description Like everyone, cows enjoy variety. Their current fancy is new shapes for pastures. The o ...