IEnumeratorIEnumerable这两个接口单词相近、含义相关,傻傻分不清楚。
入行多年,一直没有系统性梳理这对李逵李鬼。

最近本人在怼着why神的《其实吧,LRU也就那么回事》,方案1使用数组实现LRU,手写算法涉及这一对接口,借此时机覆盖这一对难缠的冤家。

IEnumerator

IEnumerator、IEnumerable接口有相似的名称,这两个接口通常也在一起使用,它们有不同的用途。

IEnumerator接口为类内部的集合提供了迭代方式, IEnumerator 要求你实现三个方法:

  • MoveNext方法:该方法将集合索引加1,并返回一个bool值,指示是否已到达集合的末尾。

  • Reset方法:它将集合索引重置为其初始值-1,这会使枚举数无效。

  • Current方法: 返回position位置的当前对象

IEnumerable

IEnumerable接口为foreach迭代提供了支持,IEnumerable要求你实现GetEnumerator方法。

public IEnumerator GetEnumerator()
{return (IEnumerator)this;
}

该用哪一个接口?

仅凭以上辞藻,很难区分两个接口的使用场景。

IEnumerator接口定义对类中的集合类型对象的迭代方式

IEnumerable接口允许使用foreach循环进行枚举。

因此IEnumerable接口的GetEnumerator方法会返回一个IEnumerator接口。要实现IEnumerable,你还必须实现IEnumerator

从英文词根上讲:
IEnumerator接口代表了枚举器,里面定义了枚举方式,是名词。
IEnumerable接口代表该对象具备了可被枚举的性质,是形容词。

总之,如果您想提供对foreach的支持,那么就先让对象可枚举,再谈论枚举方式,也就是说实现这两个接口。

最佳实践

  • 在嵌套类中实现IEnumerator,这样你可以创建多个枚举器。

  • 为IEnumerator的Current方法提供异常处理。
    为什么要这么做?
    如果集合的内容发生变化,则reset方法将被调用,紧接着当前枚举数无效,您将收到一个IndexOutOfRangeException异常(其他情况也可能导致此异常)。所以执行一个Try…Catch块来捕获这个异常并引发InvalidOperationException异常, 提示在迭代时不允许修改集合内容。

这也正是我们常见的在foreach 里面尝试修改迭代对象会报InvalidOperationException异常的原因。

下面以汽车列表为例实现IEnumerator IEnumerable接口

using System;
using System.Collections;
namespace ConsoleEnum
{public class cars : IEnumerable{private car[] carlist;//Create internal array in constructor.public cars(){carlist= new car[6]{new car("Ford",1992),new car("Fiat",1988),new car("Buick",1932),new car("Ford",1932),new car("Dodge",1999),new car("Honda",1977)};}//private enumerator classprivate class  MyEnumerator:IEnumerator{public car[] carlist;int position = -1;//constructorpublic MyEnumerator(car[] list){carlist=list;}private IEnumerator getEnumerator(){return (IEnumerator)this;}//IEnumeratorpublic bool MoveNext(){position++;return (position < carlist.Length);}//IEnumeratorpublic void Reset(){position = -1;}//IEnumeratorpublic object Current{get{try{return carlist[position];}catch (IndexOutOfRangeException){throw new InvalidOperationException();}}}}  //end nested classpublic IEnumerator GetEnumerator(){return new MyEnumerator(carlist);}}
}

foreach cars的时候,可以明显看到

  • foreach语法糖初次接触可枚举的cars, 实际会访问cars实现的 GetEnumerator()方法,拿到迭代器

  • foreach每次迭代,实际会访问迭代器的Current属性

关注并星标我们
更多干货及最佳实践分享

2021年了,`IEnumerator`、`IEnumerable`接口还傻傻分不清楚?相关推荐

  1. C# IEnumerator IEnumerable接口

    ​前言 使用linq的时候大家应该都知道IEnumerable和IEnumerator接口! 解释一下 IEnumerable 它利用 GetEnumerator() 返回 IEnumerator 集 ...

  2. C# IEnumerator/IEnumerable

    迭代器模式 与 C# IEnumerator/IEnumerable Jul 21, 2018 | 编程 |  阅读 迭代器模式 与 C# IEnumerator/IEnumerable Part1 ...

  3. unity的C#学习——foreach循环相关:IEnumerable接口、LINQ语言集成查询、可枚举对象与枚举类型

    文章目录 C#里的判断和循环 1.foreach循环 2.IEnumerable接口 3.LINQ语言集成查询 4.可枚举对象和枚举类型的区别 C#里的判断和循环 C#和C语言都有条件语句和循环语句, ...

  4. aop point 只能获取到map嘛_面试被问了几百遍的 IoC 和 AOP ,还在傻傻搞不清楚?...

    这篇文章会从下面从以下几个问题展开对 IoC & AOP 的解释 什么是 IoC? IoC 解决了什么问题? IoC 和 DI 的区别? 什么是 AOP? AOP 解决了什么问题? AOP 为 ...

  5. (1)学习数组,集合,IEnumerable接口,引申学习迭代器

    发展:数组-->集合-->泛型 (1)数组 1. 数组数据结构是System.Array类的一个实例. 2. System.Array类的语法为 [SerializableAttribut ...

  6. IEnumerable是否应该实现IEnumerable接口

    C#2.0的遍历器(Iterator),应该是对Gamma提出的Iterator设计模式的实现.在C#中,如果某个类型继承了接口IEnumerable,或者继承了泛型接口IEnumerable < ...

  7. IEnumerator,IEnumerable,IEnumerableT

    1 接口IEnumerator,IEnumerable区别IEnumerable是一个声明式的接口,声明实现该接口的类就是"可迭代的enumerable",但并没用说明如 何实现迭 ...

  8. IEnumerable接口

    实现IEnumerable接口的类可以进行简单迭代,例如foreach语句 using System; using System.Collections.Generic; using System.T ...

  9. IEnumerator/ IEnumerable/ yield return/ StartCoroutine 详解

    Update逻辑 IEnumerator/ IEnumerable public interface IEnumerable { IEnumerator GetEnumerator(); } publ ...

最新文章

  1. 第15章节-Python3.5-Django实现用户登录与前端交互2 14
  2. JavaScript 中 window.setTimeout() 的详细用法
  3. Tutorial on Variational AutoEncoders
  4. django避免写models.py办法
  5. vite2.1 最新alias别名设置方式
  6. C/C 语言printf()
  7. FB面经Prepare: Dot Product
  8. 近100个Spring/SpringBoot常用注解汇总!
  9. android 对象输出到文件
  10. 洛谷2863 [Usaco06JAN]牛的舞会
  11. HashMap死循环讲解(JDK1.8 之前)
  12. setuna截图怎么放大缩小_手机中的望远镜 华为P30pro是怎么做到50倍变焦?
  13. Oracle日志报03113,OracleORA-03113 ORA-600 [4193]故障处理
  14. 《随机过程》重点考点整理|复习笔记
  15. 【愚公系列】2022年04月 微信小程序-image图片
  16. win10更新后没有计算机了,win10更新后 ,没有处理器电源管理怎么办?
  17. Mysql primary key主键冲突的可能性与解决方案
  18. Error: Incorrect contents fetched, please reload.
  19. 微软 bing 壁纸 每日一图 bing api
  20. java中返回两个参数问题

热门文章

  1. 利用airTest的图像实别技术测试Web应用
  2. RecycleView弹性滑动
  3. Python --- 卸载
  4. ELK之elasticsearch5.6的安装和head插件的安装
  5. mooc- 基本程序设计方法week1,week2
  6. [矩形并-扫描线-线段树]Picture
  7. Tomcat(Windows)
  8. SQL利用Case When Then多条件判断
  9. 在Windows 7 Media Center中创建音乐播放列表
  10. php旧版本windows_Windows的旧版本中如何进行多任务处理?