C#有很多接口 ,这些接口牵扯一些复杂的算法问题,让很多新手对这些接口很难理解,尤其是IEnumerator和IEnumerable这两个接口,在IEnumeratorIEnumerable会让新手很糊涂:

首先,在看这篇文章的时候,你一定要清晰的知道 泛型 代表着一种类型,这种类型可以是任意类型。这才有了LIST的概念。T可以承载任意类型。很多培训机构在讲泛型的时候直接就是 Array ArrayList List告诉你怎么用,可为什么这样用,到底他们的运行机制等等一系列概念抽象的问题,老师一概而过。尤其到后面的Linq WPF MVC一些项目实战中,大量会用到这些概念,如果你没有掌握,后面基本上也只是照猫画虎,等真正遇到项目问题的时候,你会变得素手无策。不闲扯了,文章中有 不对的地方,还望各位大牛批评指正。

IEnumerator和IEnumerable的区别
① IEnumarator 是一个真正的集合访问器,提供在普通即可中遍历的接口 有 Current,MoveNext()
Reset() 其中Current返回时object类型
② IEnumerable 是暴露一个IEnumerator(只包含一个抽象方法GetEnumerator() 该方法返回一个可
以用于循环访问集合的IEnumarator对象) 支持在普通集合中遍历
③ IEnumerator 继承自IEnumerator 有Current属性 返回的是T类型
④ IEnumerable 继承自IEnumerable 暴露一个IEnumerator 支持在泛型集合中遍历
⑤ public Interface IEnumerable //告知调方对象的子项可以枚举
{
IEnumerator GetEnumerator();
}
⑥ public interface IEnumerator // 允许调方获取一个容器的子项
{
bool MoveNext();
object Current{get;}
void Reset() 将游标重置到第一个成员前面
}
IEnumerable和IEnumerator之间的关系,以及foreach的运行原理.
1> 如果一个存放集合元素的类的对象,没有实现IEnmerable 不能使用foreach()语句进行遍历
① 我们我们循环遍历的都是对象而不是类,只是这个对象时一个集合
2> 当存放集合元素的类实现 IEnumerable //这时用foreach()遍历Garage对象的值时,得到了
每一个Gra对象的值.
3>IEnumerable接口的GetEnumerator() 返回集合中的子集 是foreach()遍历的基础.

          public   class Garage: IEnumerable
{Car[] carArray = {new Car("Resty",30),new Car("Clunker",50),new Car("Zippy",30),new Car("Fred",45)};public IEnumerator GetEnumerator(){return OneCar(this);}private class OneCar : IEnumerator//私有的内部类, 实现了IEnumerator的方法{private int position = -1;//对元素进行定位private Garage t;//元素类型的集合public OneCar(Garage t) //添加元素的集合{this.t = t;}  public object Current  //获取当前元素  实现 IEnumerator结构的属性{get {return t.carArray[position];}}public bool MoveNext()  //  实现了IEnumerator的MoveNext()方法{if (position < t.carArray.Length - 1) //判断当前位置是否超过元素集合,如果没有继续下移{position++; 增加一位return true; 返回true 游标下移}else{return false; 返回false 游标停止}}public void Reset()  //  实现了IEnumerator接口的Reset()方法{position = -1; //初始化元素的位置}}
}

4> IEnumerable接口
① IEnumerable接口的集合,是强类型的,它为子对象的迭代提供类型更加安全的方式
② T 类型 它并不是代表是集合,而是确定集合中的类型 ,当用class 类名 说明这个类一个泛型类,
也是一个集合类.
③ 实现IEnumerable接口模仿List

    public class ListTest<T> : IEnumerable<T>
{private ArrayList Arrayst=new ArrayList();       public ListTest(params T[] init){         //将定义数组的元素好处,可以实现初始化时,自动添加对象的引用foreach (var item in init)  //将数组元素转换成Arraylist集合{Arrayst.Add(item);}            }public void addItem(T t){Arrayst.Add(t);//添加数组元素}public T this[int index]  //定义所引起通过下标访问 集合元素{get {if (index < 0 || index >= Arrayst.Count) {index = 0;//输入数组不正确,自动返回第一个元素}return (T)Arrayst[index];}set{Arrayst[index]= value; //通过下标修改元素的值}}public int GetNum(){return Arrayst.Count; //返回集合的长度}public IEnumerator GetEnumerator()//IEnumerable 接口的方法{ListIEnumer listIEnumer = new ListIEnumer(this);return listIEnumer;}IEnumerator<T> IEnumerable<T>.GetEnumerator() =>(IEnumerator<T>) GetEnumerator();//IEnumerable<T> 接口的方法    private  class ListIEnumer: IEnumerator<T> //实现 IEnumerator<T>的内部类{private int position = -1;//定义游标private ListTest<T> t = new ListTest<T>(); //定义当前类的集合public ListIEnumer(ListTest<T> t) //创建构造函数,获取当前类的实例{this.t = t;}public object Current{get{return this.t.Arrayst[position];//访问当前类实力集合中的元素}}T IEnumerator<T>.Current =>(T) Current; //访问当前类实例集合的元素public bool MoveNext()// 判断被访问的元素,下一游标{if (position < t.Arrayst.Count - 1){position++;return true;}else{return false;}}public void Reset(){position = -1;}//Dispose方法 系统自动生成private bool disposedValue = false; // 要检测冗余调用protected virtual void Dispose(bool disposing){if (!disposedValue){if (disposing){// TODO: 释放托管状态(托管对象)。}// TODO: 释放未托管的资源(未托管的对象)并在以下内容中替代终结器。// TODO: 将大型字段设置为 null。disposedValue = true;}}// TODO: 仅当以上 Dispose(bool disposing) 拥有用于释放未托管资源的代码时才替代终结器。// ~ListIEnumer() {//   // 请勿更改此代码。将清理代码放入以上 Dispose(bool disposing) 中。//   Dispose(false);// }// 添加此代码以正确实现可处置模式。public void Dispose(){// 请勿更改此代码。将清理代码放入以上 Dispose(bool disposing) 中。Dispose(true);// TODO: 如果在以上内容中替代了终结器,则取消注释以下行。// GC.SuppressFinalize(this);}}

自定义ArrayLIst的实现

 public  class LinkedListNode{        public LinkedListNode(object value){Value = value;}public object Value { get; }//获取当前元素public LinkedListNode Next { get; internal set; } //返回下一个元素public LinkedListNode Prev { get; internal set; }//返回上一个元素}public  class LinkedList: IEnumerable{    public LinkedListNode First { get; private set; }public LinkedListNode Last { get; private set; }public LinkedListNode AddLast(object node) //添加元素{var newNode = new LinkedListNode(node); //定义集合类if (First == null){First = newNode;Last = First;}else{               Last.Next = newNode;Last = newNode;            }return newNode;}public IEnumerable GetEnumerator() //IEnumerable接口的实现{LinkedListNode current = First;while (current != null){yield return current.Value;//  yield return 这是迭代替返回集合的一个元素,并移动到下一个元素上.这种方式也能强类型的list<T>//相关属性和类名给出<T>就好了,不过很不容易理解,因为在这里就是迭代,内容抽象。current = current.Next;}            }IEnumerator IEnumerable.GetEnumerator(){throw new System.NotImplementedException();}}

C# IEnumerator和IEnumerable的区别相关推荐

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

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

  2. C# IQueryable 和 IEnumerable 的区别

    这是 EF Core 系列的最后一篇文章,按照上一篇的计划,我们最后就讲一讲 IQueryable 和 IEnumerable 的区别. 点击上方或后方蓝字,阅读 EF Core 系列合集. 在前面的 ...

  3. 【C#】IQueryable和IEnumerable的区别

    IEnumerable接口 公开枚举器,该枚举器支持在指定类型的集合上进行简单迭代.也就是说:实现了此接口的object,就可以直接使用foreach遍历此object: IQueryable 接口 ...

  4. IQueryable 和 IEnumerable 的区别

    在C#中使用 Linq to sql 时,经常搞混 IQueryable 和 IEnumerable 这两种类型,本文简单分析下它们之间的区别和使用场景. 前言 不管是Linq to object,还 ...

  5. EFCore——IQueryable与IEnumerable的区别(13)

    IQueryable与IEnumerable的区别 一.IQueryable与IEnumerable的简单实例 二.IQueryable与IEnumerable的区别 一.IQueryable与IEn ...

  6. IEnumerator和IEnumerable

    IEnumerable和IEnumerator两个接口的语法定义.其实IEnumerable接口是非常的简单,只包含一个抽象的方法GetEnumerator(),它返回一个可用于循环访问集合的IEnu ...

  7. C#中IQueryable和IEnumerable的区别

    IQueryable接口是继承自IEnumerable的接口 IQueryable中有表达式树, 这可以看作是它的一个优势.所以,使用IQueryable操作时,比如对数据的过滤,排序等操作, 这些都 ...

  8. IQueryable和IEnumerable的区别

    转载于:https://www.cnblogs.com/myyBlog/p/8961062.html

  9. IEnumerator,IEnumerable,IEnumerableT

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

最新文章

  1. [bzoj4922]Karp-de-Chant Number
  2. php双层foreach,php 双层foreach 如何提升效率
  3. 小白自学深度学习——目录
  4. codechef LEMOVIE dp
  5. “一键删除中国App”应用海外走红,下载量破500万!谷歌:我先把你删除了
  6. oracle 日期 加一秒,Leap Second (闰秒) 在ORACLE环境的影响
  7. kettle-查询控件
  8. mysql like 大小写_mysql - 如何使用LIKE通配符在列中搜索(不区分大小写)?
  9. oracle判断一个值不在记录中,Oracle: DELETE前不需SELECT判断记录是否存在,INSERT前不需SELECT判断是否有若干字段值重复的记录。...
  10. 阶段3 3.SpringMVC·_07.SSM整合案例_09.ssm整合之Spring整合MyBatis框架配置事务
  11. Java内存模型—JMM详解
  12. 旋风加速浏览器安卓android,旋风加速浏览器免费两个小时
  13. 非线性最小二乘法曲线拟合
  14. 博科Brocade 6505光纤交换机
  15. 双重差分法之平行趋势检验
  16. Eclipse背景颜色设置(设置成豆沙绿色保护眼睛)
  17. 计算机的任务管理器不显示不出来,开机后桌面不显示图标,也调不出任务
  18. numpy矩阵升维,拼接
  19. 狗民网:狗与爱的世界
  20. 今天不聊技术,聊聊如何成为一个靠谱的软件从业人员

热门文章

  1. 一分钟看懂“设备数据采集”神器
  2. 3D电子沙盘构建方法与实现的方案
  3. python可以应用lbm_格子玻尔兹曼方法(LBM)Python 程序提速
  4. 软件需求可测试性,软件需求管理与可跟踪性
  5. Fseek()与Ftell()函数的作用
  6. 【云杂谈】《公共云被用于黑客和恐怖活动的风险》
  7. 实用博客||工具||网页收藏导航(持续更新)
  8. springboot整合security(一)入门
  9. 第三期_Metasploit 介绍《Metasploit Unleashed Simplified Chinese version(Metasploit官方文档教程中文版)》
  10. AI开放平台:发布车辆五项信息、投保日期在线查询api接口