本质:实现了一个IEnumerable接口,

01.为什么数组和集合可以使用foreach遍历?

解析:因为数组和集合都实现了IEnumerable接口,该接口中只有一个方法,GetEnumerator()

02.数组是一种数据结构,它包含若干相同类型的变量。数组是使用类型声明的:type[] arrayName;

03.数组类型是从抽象基类型 Array 派生的引用类型。由于此类型实现了 IEnumerable ,因此可以对 C# 中的所有数组使用 foreach 迭代。(摘自MSDN)

我们都知道foreach可以遍历ArrayList集合

我们可以F12过去看看它的内部微软写好的代码

01.

.

02.

03.

04.

下面我们自己来模拟实现微软的方法:

1.MyCollection类实现IEnumerable接口

  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Text;
  6. using System.Threading.Tasks;
  7.  
  8. namespace Foreach原理
  9. {
  10. //自定义类型:实现IEnumerable接口,证明这个类型保存的数据能被foreach遍历
  11. public class MyCollection : IEnumerable
  12. {
  13. //01给集合添值得方法
  14. public void Add(object o)
  15. {
  16. list.Add(o);
  17. }
  18. //02定义一个集合
  19. ArrayList list = new ArrayList();
  20. //03实现GetEnumerator方法
  21. public IEnumerator GetEnumerator()
  22. {
  23. return new MyIEnumerator(list);
  24. }
  25. }
  26. }

02.MyIEnumerator类实现IEnumerator接口

  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Text;
  6.  
  7. namespace Foreach原理
  8. {
  9. //IEnumerator:支持对非泛型集合的简单迭代
  10. public class MyIEnumerator : IEnumerator
  11. {
  12. //定义一个List集合
  13. ArrayList list = new ArrayList();
  14.  
  15. public MyIEnumerator(ArrayList mylist)
  16. {
  17. //给当前类的集合赋值
  18. list = mylist;
  19. }
  20. //默认将集合的索引指向前一个 即第一条数据之前
  21. private int i = -1;
  22.  
  23. //返回当前循环遍历索引的值
  24. public object Current
  25. {
  26. get { return list[i]; }
  27. }
  28. //实现接口的Movenext方法
  29. public bool MoveNext()
  30. {
  31. bool flag = false;//默认为没有数据
  32. if (i < list.Count - 1)
  33. {
  34. //证明集合中有数据让索引加1
  35. i++;
  36. //改变bool值为true
  37. flag = true;
  38. }
  39. return flag;
  40. }
  41. //把i初始化为-1
  42. public void Reset()
  43. {
  44. i = -1;
  45. }
  46. }
  47. }

03.在Main方法中调用

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6.  
  7. namespace Foreach原理
  8. {
  9. class Program
  10. {
  11. static void Main(string[] args)
  12. {
  13. //01.实例化实现了IEnumerable接口的MyCollection类
  14. MyCollection list = new MyCollection();
  15. //02.向集合添加元素
  16. list.Add("小张");
  17. list.Add("小王");
  18. //03.方可使用foreach循环遍历出结果
  19. foreach (string item in list)
  20. {
  21. Console.WriteLine(item);
  22. }
  23. Console.ReadKey();
  24. }
  25. }
  26. }

这就是foreach遍历集合或数组的原理或实质。

分享面试题------

Foreach原理的更多相关文章

  1. .net学习之集合、foreach原理、Hashtable、Path类、File类、Directory类、文件流FileStream类、压缩流GZipStream、拷贝大文件、序列化和反序列化

    1.集合(1)ArrayList内部存储数据的是一个object数组,创建这个类的对象的时候,这个对象里的数组的长度为0(2)调用Add方法加元素的时候,如果第一次增加元神,就会将数组的长度变为4往里 ...

  2. Array.forEach原理,仿造一个类似功能

    Array.forEach原理,仿造一个类似功能 array.forEach // 设一个arr数组 let arr = [12,45,78,165,68,124]; let sum = 0; // ...

  3. 浅析foreach原理

    在日常开发工作中,我们发现很多对象都能通过foreach来遍历,比如HashTable.Dictionary.数组等数据类型.那为何这些对象能通过foreach来遍历呢?如果写一个普通的Person类 ...

  4. C#学习笔记:foreach原理

    这篇随笔是对上一篇随笔C#关键字:yield的扩展. 关于foreach 首先,对于 foreach ,大家应该都非常熟悉,这里就简单的描述下. foreach 语句用于对实现  System.Col ...

  5. C#foreach原理

    本文主要记录我在学习C#中foreach遍历原理的心得体会. 对集合中的要素进行遍历是所有编码中经常涉及到的操作,因此大部分编程语言都把此过程写进了语法中,比如C#中的foreach.经常会看到下面的 ...

  6. Foreach 原理

    public class Person { private string[] friends = { "asf", "ewrqwe", "ddd&qu ...

  7. C# foreach 原理以及模拟的实现

    public class Person:IEnumerable     //定义一个person类  并且 实现IEnumerable 接口  (或者不用实现此接口 直接在类 //里面写个GetEnu ...

  8. 涉及 C#的 foreach问题

    当时是用foreach实现遍历,但是函数传入参数是Object类型的,由于Objectl类型没有实现相关接口,所以foreach并不能执行. 那么下面我们来看看,想要使用foreach需要具备什么条件 ...

  9. mybatis foreach 循环 list(map)

    直接上代码: 整体需求就是: 1.分页对象里面有map map里面又有数组对象 2.分页对象里面有list list里面有map map里面有数组对象. public class Page { pri ...

随机推荐

  1. vuejs件同一个挂载点上切换组

    vuejs件同一个挂载点上切换组 动态组件 http://cn.vuejs.org/guide/components.html#动态组件 多个组件可以使用同一个挂载点,然后动态地在它们之间切换.使用保 ...

  2. IOS开发之控件篇UINavigationController第一章 - 介绍

    UINavigationController是一个比较常见的控件,它连接个视图,例如一个视图走到另外一个视图,之间的联系都可以用这个NavigationController的方法 一般都会由两个部分组 ...

  3. Java EE开发平台随手记3——Mybatis扩展2

    忙里偷闲,继续上周的话题,记录Mybatis的扩展. 扩展5:设置默认的返回结果类型 大家知道,在Mybatis的sql-mapper配置文件中,我们需要给<select>元素添加resu ...

  4. Vertex and Fragment Shader

    Semantics语义词: 定义:GPU工作时,数据通常暂存在寄存器,那么在Cg中,语义词就指定了输入/输出数据和图形硬件寄存器之间的映射关系. 原理:根据输入语义,图形处理器从某个寄存器取数据:然后 ...

  5. Representation Data in OpenCascade BRep

    Representation Data in OpenCascade BRep eryar@163.com 摘要Abstract:现在的显示器大多数是光栅显示器,即可以看做一个像素的矩阵.在光栅显示器 ...

  6. 《BI那点儿事》Microsoft 聚类分析算法——三国人物身份划分

    什么是聚类分析? 聚类分析属于探索性的数据分析方法.通常,我们利用聚类分析将看似无序的对象进行分组.归类,以达到更好地理解研究对象的目的.聚类结果要求组内对象相似性较高,组间对象相似性较低.在三国数据 ...

  7. 使用selenium+phantomJS实现网页爬取

    有些网站反爬虫技术设计的非常好,很难采用WebClient等技术进行网页信息爬取,这时可以考虑采用selenium+phantomJS模拟浏览器(其实是真实的浏览器)的方式进行信息爬取.之前一直使用的 ...

  8. HTML&CSS学习总结(一)

    上周用了一周的时间,周一到周五平均每天2-3小时,周六.周日每天各8小时,看网易云课堂燕十八的HTML+div+CSS视频,感觉还不错,按照视频的讲课思路大概做个总结吧. 基本思路:从大的方面(整体结 ...

  9. 页面copyright部分始终居于页面底部

    <!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content ...

  10. Spring定时器,定时执行(quartz)

    这个定时器与继承了timertask的定时器不同的是,这个定时器是更强大的,可以指定每分的第n秒,每天的第n时,每周的.每年的.来定时运行这个定时器.那么下面来讲诉如何使用quartz定时器. spr ...