​前言

使用linq的时候大家应该都知道IEnumerable和IEnumerator接口!

解释一下

  • IEnumerable 它利用 GetEnumerator() 返回 IEnumerator 集合访问器,声明实现该接口的class是“可枚举(enumerable)”的 通俗点说就是可进行迭代操作的类型。

  • IEnumerator解释:它是一个的集合访问器,使用foreach语句遍历集合或数组时,就是调用 Current、MoveNext()的结果。

例子

今天给大家讲讲迭代器的原理 我们自己实现一个UserInforMationList

我这里定义一个UserInforMationModel和UserInforMationList类

public class UserInforMationList{public UserInforMation[] _UserInforMations;public void Add(UserInforMation[] userInforMations){_UserInforMations = new UserInforMation[userInforMations.Length];for (int i = 0; i < userInforMations.Length; i++){_UserInforMations[i] = userInforMations[i];}}}
  public class UserInforMation{public string UserName { get; set; }public string Sex { get; set; }}

使用我们的测试方法,发现我们的代码报错了UserInforMationList不包含 GetEnumerator的公共实例,因此不能使用ForEach.

那么我们要怎么实现Foreach了那就要用到IEnumerator、IEnumerable!

提示告诉我们缺少一个GetEnumerator的公共实例

我们看下IEnumerable接口

    public interface IEnumerable{[DispId(-4)][__DynamicallyInvokable]IEnumerator GetEnumerator();}

Enumerable接口刚好返回一个GetEnumerator 然后再看一下IEnumerator

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

public interface IEnumerator{[__DynamicallyInvokable]object Current{[__DynamicallyInvokable]get;}[__DynamicallyInvokable]bool MoveNext();[__DynamicallyInvokable]void Reset();}

看了这两个接口就可以知道我们的UserInforMationList:要继承这个IEnumerable接口 这个接口返回的是一个GetEnumerator。观察这方法,

    public IEnumerator GetEnumerator(){throw new NotImplementedException();}

需要返回一个叫做IEnumerator的接口,因此,一个类要想可迭代,还需要进一步实现IEnumerator类,这个才是真正获取到的迭代器,

那我们再定义一个UserInforMationEnumerator继承于GetEnumerator然后实现这三个方法,

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

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

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

public class UserInforMationEnumerator : IEnumerator{public UserInforMation[] _userInforMations;public int _Index = -1;public UserInforMationEnumerator(UserInforMation[] userInforMations){_userInforMations = userInforMations;}public object Current => _userInforMations[_Index];public bool MoveNext(){_Index++;return _Index < _userInforMations.Length;}public void Reset(){_Index = -1;}}

这样我们就实现了自己的迭代器。

然后我们跑一下代码

我们调用GetEnumerator的时候,看似里面for循环了一次,其实这个时候没有做任何操作。只有调用MoveNext的时候才会对应调用for循环:

现在我想可以回答你为什么Linq to Object中要返回IEnumerable?:

因为IEnumerable是延迟加载的,每次访问的时候才取值。也就是我们在Lambda里面写的where、select并没有循环遍历(只是在组装条件),只有在ToList或foreache的时候才真正去集合取值了。这样大大提高了性能。

最后大家如果喜欢我的文章,还麻烦给个关注并点个赞, 希望net生态圈越来越好!

微信公众号:黑哥聊dotNet

C# IEnumerator IEnumerable接口相关推荐

  1. 2021年了,`IEnumerator`、`IEnumerable`接口还傻傻分不清楚?

    IEnumerator.IEnumerable这两个接口单词相近.含义相关,傻傻分不清楚. 入行多年,一直没有系统性梳理这对李逵李鬼. 最近本人在怼着why神的<其实吧,LRU也就那么回事> ...

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

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

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

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

  4. IEnumerator,IEnumerable,IEnumerableT

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

  5. IEnumerable接口

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

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

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

  7. C# IEnumerator/IEnumerable

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

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

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

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

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

最新文章

  1. 华为Mate 30系列发布:电影级4摄,麒麟990 5G,没谷歌全家桶,售价高于iPhone11
  2. .net里鼠标选中的text数据怎么获取_怎么利用Excel设置当天生日提醒功能
  3. 十六进制数转换成float类型数据数据的经典代码
  4. hud抬头显示器哪个好_汽车加装HUD抬头显示实用吗?不低头就能获取数据
  5. Python|凯撒密码加密字符串
  6. 21岁开始练字晚不晚?
  7. 『Python学习笔记』ZipFile解压中文路径乱码[以及rar、7z解压方法]
  8. php 公众号管理系统源码,SmartWx微信公众号管理系统 v2.0
  9. OutLook添加网易邮箱,QQ邮箱
  10. 右键后资源管理器重启
  11. PaddlePaddle 波斯顿房价预测训练结果
  12. vue生命周期(简短精干篇)
  13. Unicode编码和Base64编码
  14. 图片打开太暗看不清并且手机传给电脑的视频打开卡
  15. 华为手机百度云息屏后停止下载_华为智选车载智慧屏评测:像手机一般好用,行车体验更便捷...
  16. html页面中漂浮物怎么实现,html的section标签是什么怎么用了
  17. 恭喜大家不用升级android11,恭喜,大家不用升级安卓11了
  18. python用pip安装numpy完整命令_Python--Numpy安装
  19. Win10 20H2更新出错:无法保留你的文件、应用和设置,因为你当前的Windows版本可能安装在不受支持的目录中,或者你正在尝试安装更旧版本的Windows
  20. 高权重网站后面的共同点

热门文章

  1. ACDSee Pro 6.0.169 (x86) crack by XenoCoder
  2. 如何使用python股票实时接口查出股票信息?
  3. 【翻译】和麻美学姐一起的世界树(マミさんと世界樹スレ)第五话
  4. 云呐|教育卫生行业固定资产管理系统软件流程
  5. 黑马有信将新装辟蓝海
  6. 这是网络工程师最详细的必备软件整理,附最新安装包
  7. SAS更新SID出现ERROR: 锁对“SASHELP.CORE.CATALOG”不可用
  8. matlab与excel标准差不一样,matlab计算结果和excel完全不一样
  9. 爱奇艺HomeAI智能语音交互系统的技术实践
  10. 落地页转化分析,你还在用漏斗模型?