引言

IEnumerable是可枚举的所有非泛型集合的基接口, IEnumerable包含一个方法GetEnumerator(),该方法返回一个IEnumerator;IEnumerator提供通过Current属性以及MoveNext()和Reset()方法来循环访问集合的功能。

IEnumerable 接口

公开枚举数,该枚举数支持在非泛型集合上进行简单迭代。接口源码如下:

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

IEnumerator 接口

支持对非泛型集合的简单迭代。接口源码如下:

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

举例说明

示例演示了通过实现IEnumerable和IEnumerator接口来循环访问自定义集合的最佳实践。

定义一个简单的实体类:

public class Person{public Person(string name, int age){this.Name = name;this.Age = age;}public string Name;public int Age;}

定义一个实体类的集合,继承IEnumerate:

 public class People : IEnumerable{private Person[] _people;public People(Person[] pArray){_people = new Person[pArray.Length];for (int i = 0; i < pArray.Length; i++){_people[i] = pArray[i];}}/// <summary>/// GetEnumerator方法的实现/// </summary>/// <returns></returns>
        IEnumerator IEnumerable.GetEnumerator(){return GetEnumerator();}public PeopleEnum GetEnumerator(){return new PeopleEnum(_people);}}

定义一个枚举器,继承IEnumerator:

public class PeopleEnum : IEnumerator{public Person[] _people;/// <summary>/// 枚举器位于第一个元素之前直到第一个MoveNext()调用。/// </summary>private int position = -1;public PeopleEnum(Person[] list){_people = list;}public bool MoveNext(){position++;return position < _people.Length;}public void Reset(){position = -1;}object IEnumerator.Current => Current;public Person Current{get{try{return _people[position];}catch (IndexOutOfRangeException){throw new InvalidOperationException();}}}}

具体调用:

 Person[] peopleArray = new Person[3]{new Person("张三", 15),new Person("李四", 18),new Person("王五", 21),};People peopleList = new People(peopleArray);foreach (Person p in peopleList)Console.WriteLine(p.Name + "\t" + p.Age);

输出:

其中,上边调用中foreach等价于

IEnumerator enumeratorSimple = peopleList.GetEnumerator();
while (enumeratorSimple.MoveNext()){Person p = enumeratorSimple.Current as Person;Console.WriteLine(p?.Name + "\t" + p?.Age);}

通过例子,可以得出:

  • 实现一个自定义集合,继承于IEnumerate,必须实现一个枚举器;
  • C# 语言的foreach语句隐藏了枚举数的复杂性,因此, 建议foreach使用, 而不是直接操作枚举器;
  • 枚举器可用于读取集合中的数据,但不能用于修改基础集合。

总结

IEnumerable代表继承此接口的类(比如ArrayList,IList,List<T>等)可以获取一个IEnumerator来实现枚举这个类中包含的集合中的元素的功能,是 .NET Framework 中最基本的集合访问器。在编程中,Lambda表达式通过Select()或者Where()返回的变量为IEnumerate<T>,此时我们可以通过foreach遍历。希望本文对你有所帮助,下一篇介绍Lambda中的Select和Where,感兴趣的朋友可以加关注,欢迎留言交流!

IEnumerable和IEnumerator详解相关推荐

  1. IEnumerable和IEnumerator 详解

    IEnumerable接口是非常的简单,只包含一个抽象的方法GetEnumerator(),它返回一个可用于循环访问集合的IEnumerator对象.IEnumerator对象有什么呢?它是一个真正的 ...

  2. IEnumerable 使用foreach 详解

    自己实现迭代器 yield的使用 怎样高性能的随机取IEnumerable中的值 我们先思考几个问题: 为什么在foreach中不能修改item的值? 要实现foreach需要满足什么条件? 为什么L ...

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

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

  4. C#语言入门详解13-19

    文章目录 十三.十四.十五.十六.表达式,语句详解 框架 表达式的定义 各类表达式的概览 语句的定义 语句详解 声明语句 表达式语句 块语句 选择(判断.分支)语句 try语句 迭代语句 跳转语句 十 ...

  5. 刘铁锰老师C#语言入门详解(委托事件等部分有详细代码和注释)

    目录 1.初识类 1.1 类与对象的关系 1.2 类的三大成员 1.3 静态成员与实例成员 1.4 类修饰符 2.构成C#语言的基本元素 2.1 六个基本元素 2.2 算法简介 3. 详解类型.变量与 ...

  6. unity3d 切换网络_Unity3d新网络请求方式UnityWebRequest详解

    Unity将要逐步放弃www网络请求api,新的api请求方式来临:UnityWebRequestThe,也正是本篇文章要给大家介绍的重点,那就是UnityWebRequestThe的使用详解. 旧的 ...

  7. ASP.NET MVC Controller激活系统详解:默认实现

    Controller激活系统最终通过注册的ControllerFactory创建相应的Conroller对象,如果没有对ControllerFactory类型或者类型进行显式注册(通过调用当前Cont ...

  8. ASP.NET Core的配置(2):配置模型详解

    在上面一章我们以实例演示的方式介绍了几种读取配置的几种方式,其中涉及到三个重要的对象,它们分别是承载结构化配置信息的Configuration,提供原始配置源数据的ConfigurationProvi ...

  9. 基础拾遗------泛型详解

     基础拾遗: 前言: 1.泛型的约束 2.泛型继承 3.关键字default 4.泛型方法 5.泛型接口 6.泛型数组 7.泛型委托 基础拾遗: 基础拾遗------特性详解 基础拾遗------ ...

最新文章

  1. 树的高度(小米2017秋招真题)
  2. ios开发入门篇(四):UIWebView结合UISearchBar的简单用法
  3. 主成分分析(PCA)——以2维图像为例
  4. 复制(主从复制、读写分离)
  5. mysql倍增表的内容,mysql - DATEDIFF不会在触发器内倍增 - SO中文参考 - www.soinside.com...
  6. NLP中的Mask全解
  7. Visual Studio IDE环境下利用模板创建和手动配置CUDA项目教程
  8. kubernetes1.8.4 安装指南 -- 9. calico
  9. 1/2 常用函数:内建函数
  10. python123数值运算代码_Python中的变量、数据类型(数值、列表)操作实例
  11. python怎么复制上面的语句_JAVA、python、Go的复制语句
  12. 《白鹿原》金句摘抄(八)
  13. 前后端分离必备的接口规范,十分接地气
  14. 为什么出现股市二八现象?
  15. li下的ul----多级列表
  16. 可以做服务器操作系统的是,可以做服务器操作系统
  17. python中遇到的问题及解决方法_自己编程中遇到的Python错误和解决方法汇总整理...
  18. 了解更多关于11gR2 diskmon
  19. 三角形外接圆圆心计算公式
  20. iOS 适配iPhone XR/XS/XS MAX

热门文章

  1. Python_主成分分析
  2. lua——赢三张牌型处理相关算法(上)——牌值数据
  3. 2台主机的docker互相通信的方法
  4. DbHelper重用性方案 优化工具类 jdbc
  5. 谷歌浏览器的驱动下载安装与配置-0223
  6. linux-用户管理
  7. 在spring boot中三分钟上手apache顶级分布式链路追踪系统skywalking
  8. 【loj2585】【APIO2018】新家
  9. 9. 求数组任意次最值
  10. 用msvdm.dll文件实现微软的虚拟桌面