zoukankan      html  css  js  c++  java
  • IEnumerable与IEnumerator区别

    原文地址:http://blog.csdn.net/dly553709938/article/details/7214934

    1. 一个Collection要支持foreach方式的遍历,必须实现IEnumerable接口(亦即,必须以某种方式返回IEnumerator对象)。 
     
    2. IEnumerator对象具体实现了iterator(通过MoveNext(),Reset(),Current)。 
     
    3. 从这两个接口的用词选择上,也可以看出其不同:IEnumerable是一个声明式的接口,声明实现该接口的class是“可枚举(enumerable)”的,但并没有说明如何实现枚举器(iterator)IEnumerator是一个实现式的接口,IEnumerator对象就是一个iterator(迭代器)。 
     
    4. IEnumerable和IEnumerator通过IEnumerable的GetEnumerator()方法建立了连接,可以通过IEnumerable的GetEnumerator()得到IEnumerator对象。
     
    5. 由于IEnumerable<T>扩展(继承)了旧的IEnumerable接口,所以要实现两个不同的方法:
    IEnumerator<T> GetEnumerator();
    IEnumerator GetEnumerator(); // 由于和泛型版本的方法同名,所以该方法的实现需要使用显式接口实现
     
    为什么集合类不直接继承(支持)IEnumerator<T>和IEnumerator接口?
          假如同时有两个循环交错遍历同一个集合(一个foreach嵌套了另外一个foreach),那么集合必须维持当前元素的一个状态指示器,确保当调用MoveNext()方法时,能正确定位下一个元素。
     
          为了解决这个问题,集合类不直接支持IEnumerator<T>和IEnumerator接口。而是通过IEnumerable的GetEnumerator返回一个新的IEnumerator对象来负责维护循环遍历的状态,IEnumerator(迭代器,或者叫枚举数)相当于一个“游标”(cursor)或者“书签”。可以有多个书签,移动每个书签都可独立于其他书签来遍历集合。
     
    [csharp] view plaincopy
    1. class Program  
    2. {  
    3.     static void Main(string[] args)  
    4.     {  
    5.         CountingEnumerable counter = new CountingEnumerable();  
    6.         foreach (int x in counter)  
    7.         {  
    8.             Console.WriteLine(x);  
    9.         }  
    10.   
    11.         Console.ReadKey();  
    12.     }  
    13. }  
    14.   
    15. class CountingEnumerable : IEnumerable<int>  
    16. {  
    17.     public IEnumerator<int> GetEnumerator()  
    18.     {  
    19.         return new CountingEnumerator(); // 返回一个新的迭代器,是为了维护状态  
    20.     }  
    21.   
    22.     // 由于IEnumerable<T>继承IEnumerable,两个接口的GetEnumerator方法同名  
    23.     // 所以对于非泛型的IEnumerable的GetEnumerator方法使用显式接口实现。  
    24.     // (如果IEnumerable<T>没有继承IEnumerable,那么一个只支持使用非泛型IEnumerable的  
    25.     // 方法将无法使用IEnumerable<T>)  
    26.     IEnumerator IEnumerable.GetEnumerator()  
    27.     {  
    28.         return GetEnumerator(); // IEnumerator是IEnumerator<T>的基类  
    29.     }  
    30. }  
    31.   
    32. class CountingEnumerator : IEnumerator<int>  
    33. {  
    34.     int current = -1;  
    35.   
    36.     public bool MoveNext()  
    37.     {  
    38.         current++;  
    39.         return current < 10;  
    40.     }  
    41.   
    42.     public int Current { get { return current; } }  
    43.   
    44.     object IEnumerator.Current { get { return Current; } }  
    45.   
    46.     public void Reset()  
    47.     {  
    48.         current = -1;  
    49.     }  
    50.   
    51.     // IEnumerator<T>继承了IDisposable,为了遍历完后清理状态,所以需要实现该方法  
    52.     // 该方法在foreach循环完毕后自动调用  
    53.     public void Dispose() { }   
    54. }  
  • 相关阅读:
    Jqgrid学习
    【转】SpringMVC 流程图
    【转】spring学习之@SessionAttributes
    【转】HttpSessionListener, HttpSessionAttributeListener的用法
    Java会话(session)管理
    hibernate--一对多xxx.hbm.xm配置
    使用Spring容器
    最简单的hibernate入门、配置
    搭建Struts 2的工作环境
    Struts2的常用标签
  • 原文地址:https://www.cnblogs.com/hiflora/p/2811084.html
Copyright © 2011-2022 走看看