IEnumerable接口顾名思义就是 可枚举的,可列举的。

接口也很简单,返回一个 枚举器对象 IEnumerator 。

 [ComVisible(true), Guid("496B0ABE-CDEE-11d3-88E8-00902754C43A")]
public interface IEnumerable
{
[DispId(-)]
IEnumerator GetEnumerator();
}

1.  IEnumerable 与  IEnumerator

IEnumerable只有一个抽象方法:GetEnumerator(),而IEnumerator又是一个迭代器,真正实现了访问集合的功能。  IEnumerator只有一个Current属性,MoveNext和Reset两个方法。

有个小问题,只搞一个访问器接口不就得了?为什么要两个看起来很容易混淆的接口呢?一个叫枚举器,另一个叫迭代器。因为

1) 实现IEnumerator是个脏活累活,白白加了两个方法一个属性,而且这两个方法其实并不好实现(后面会提到)。

(2) 它需要维护初始状态,知道如何MoveNext ,如何结束,同时返回迭代的上一个状态,这些并不容易。

(3)迭代显然是非线程安全的,每次IEnumerable都会生成新的IEnumerator,从而形成多个互相不影响的迭代过程。在迭代过程中,不能修改迭代集合,否则不安全。

所以只要你实现了IEnumerable,编译器就会帮我们实现IEnumerator。何况绝大多数情况都是从现有集合继承,一般不需要重写MoveNext和Reset方法。 IEnumerable当然还有泛型实现,这个不影响问题的讨论。

IEnumerable也有它的缺点,它没法后退,没法跳跃(只能一个一个的跳过去),而且实现Reset并不容易,无法实现索引访问。想想看, 如果是一个实例集合的枚举过程,直接返回到第0个元素就可以了,但是如果这个IEnumerable是漫长的访问链条,想找到最初的根是很困难的!所 以CLR via C#的作者告诉你,其实很多Reset的实现根本就是谎言,知道有这个东西就行了,不要太过依赖它。

具体实现请看我的另外一篇文章 http://www.cnblogs.com/yplong/p/5286906.html

IEnumerable接口的更多相关文章

  1. C# 索引器,实现IEnumerable接口的GetEnumerator()方法

    当自定义类需要实现索引时,可以在类中实现索引器. 用Table作为例子,Table由多个Row组成,Row由多个Cell组成, 我们需要实现自定义的table[0],row[0] 索引器定义格式为 [ ...

  2. 你可能不知道的陷阱, IEnumerable接口

    1.  IEnumerable 与  IEnumerator IEnumerable枚举器接口的重要性,说一万句话都不过分.几乎所有集合都实现了这个接口,Linq的核心也依赖于这个万能的接口.C语言的 ...

  3. foreach为什么要实现IEnumerable接口而不是直接用IEnumerator接口

    在.Net中,要想被foreach遍历,那么目标对象要实现IEnumerable或IEnumerable<T>接口,这个接口有一个方法,GetEnumerator(),返回一个IEnume ...

  4. EF架构~为IEnumerable接口添加增删查等操作,原因是IEnumerable导航属性更放心

    回到目录 对EF开发来说,导航属性肯定都用过,事实上,它是由VS IDE工具根据你的数据库关系结构自动生成的外键属性,在类视图中可以看到相关属性,它是以外键表名来标识的,如果是一对多的关系,那么,它会 ...

  5. IEnumerable接口的实现

    对象要实现可以迭代需IEnumerable接口并实现GetEnumerator方法.一下简单例子 public class SPEnumerable<T> : IEnumerable { ...

  6. IEnumerable 接口 实现foreach 遍历 实例

    额 为啥写着东西? 有次面试去,因为用到的时候特别少 所以没记住, 这个单词 怎么写! 经典的面试题: 能用foreach遍历访问的对象的要求? 答:  该类实现IEnumetable 接口   声明 ...

  7. IEnumerator/IEnumerable接口

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

  8. IEnumerable接口的扩展方法

    /// <summary>/// IEnumerable接口的扩展方法,支持它的实现类是List的情况/// </summary>using System.Collection ...

  9. 一位有着工匠精神的博主写的关于IEnumerable接口的详细解析

    在此,推荐一位有着工匠精神的博主写的一篇关于IEnumerable接口的深入解析的文章:http://www.cnblogs.com/zhaopei/p/5769782.html#autoid-0-0 ...

随机推荐

  1. Codeforces Round #381 (Div. 1) A. Alyona and mex 构造

    A. Alyona and mex 题目连接: http://codeforces.com/contest/739/problem/A Description Alyona's mother want ...

  2. android设置背景半透明效果

    1.Button或者ImageButton的背景透明或者半透明 半透明:<Button android:background="#e0000000"···> 透明:&l ...

  3. LCLFramework框架之IOC

    我们都知道,在采用面向对象方法设计的软件系统中,它的底层实现都是由N个对象组成的,所有的对象通过彼此的合作,最终实现系统的业务逻辑. 借助于"第三方"实现具有依赖关系的对象之间的解 ...

  4. java模拟开锁

    java模拟开锁 service qq:928900200 Introduction to Computer Science II: CSCI142Fall 2014Lab #1Instructor: ...

  5. wordpress自动批量定时发布插件 DX-auto-publish

    DX-auto-publish是一款wordpress自动发布插件,方便实用. 该wordpress插件的主要功能如下: 1.能够自动批量定时发布wordpress站点的草稿文章,无需每篇文章都手动设 ...

  6. 封装一个UILabel圆形边框显示进度

    封装了一个UILabel并让它显示圆形的边框,UILabel上面显示百份比,而边框则用Animation绘制到整个圆占指定百分比的点. 这只是我个人想的继承一个UILabel实现的,用到两个CASha ...

  7. A cycle was detected in the build path of project

    解决Eclipse中Java工程间循环引用而报错的问题 如果我们的项目包含多个工程(project),而它们之间又是循环引用的关系,那么Eclipse在编译时会抛出如下一个错误信息: “A cycle ...

  8. 使用Flask-Migrate进行管理数据库升级

    我们在升级系统的时候,经常碰到需要更新服务器端数据结构等操作,之前的方式是通过手工编写alter sql脚本处理,经常会发现遗漏,导致程序发布到服务器上后无法正常使用. 现在我们可以使用Flask-M ...

  9. vs.php调试php使用外部的apache进行调试

    vs.php中使用外部的apache进行调试 一般phper们都会有自己配置好的开发调试环境,那么如何在vs.php中使用自己已经配置好的apache+php环境调试 php程序呢?如下: (1)从官 ...

  10. Windows Server 2008 Workstation Converter优化设置

    http://www.win2008workstation.com/windows-server-2008-workstation-converter/ If you don’t want to co ...