C#基础知识---迭代器与Foreach语句
一、Foreach语句简介
在C# 1.0中我们经常使用foreach来遍历一个集合中的元素,然而如果一个集合要支持使用foreach语句来进行遍历,这个集合一般需要IEnumerable或IEnumerable<T>接口。
因为foreach是迭代语句,要使用foreach必须要有一个迭代器才行的,而IEnumerable接口中的IEnumerator GetEnumerator()方法是返回迭代器的。
在C# 1.0中,要获得迭代器一般需要实现IEnumerable接口中的GetEnumerator()方法,然而要实现一个迭代器就必须实现IEnumerator接口。
在C# 2.0中,提供 yield关键字来简化迭代器的实现。
foreach被编译后会调用GetEnumerator来返回一个迭代器。
二、C#1.0中实现迭代器
1 using System;
2 using System.Collections;
3
4 namespace 迭代器Demo
5 {
6 class Program
7 {
8 static void Main(string[] args)
9 {
10 Friends friendcollection = new Friends();
11 foreach (Friend f in friendcollection)
12 {
13 Console.WriteLine(f.Name);
14 }
15
16 Console.Read();
17 }
18 }
19
20 /// <summary>
21 /// 朋友类
22 /// </summary>
23 public class Friend
24 {
25 private string name;
26 public string Name
27 {
28 get { return name; }
29 set { name = value; }
30 }
31 public Friend(string name)
32 {
33 this.name = name;
34 }
35 }
36
37 /// <summary>
38 /// 朋友集合
39 /// </summary>
40 public class Friends : IEnumerable
41 {
42 private Friend[] friendarray;
43
44 public Friends()
45 {
46 friendarray = new Friend[]
47 {
48 new Friend("张三"),
49 new Friend("李四"),
50 new Friend("王五")
51 };
52 }
53
54 // 索引器
55 public Friend this[int index]
56 {
57 get { return friendarray[index]; }
58 }
59
60 public int Count
61 {
62 get { return friendarray.Length; }
63 }
64
65 // 实现IEnumerable<T>接口方法
66 public IEnumerator GetEnumerator()
67 {
68 return new FriendIterator(this);
69 }
70 }
71
72 /// <summary>
73 /// 自定义迭代器,必须实现 IEnumerator接口
74 /// </summary>
75 public class FriendIterator : IEnumerator
76 {
77 private readonly Friends friends;
78 private int index;
79 private Friend current;
80 internal FriendIterator(Friends friendcollection)
81 {
82 this.friends = friendcollection;
83 index = 0;
84 }
85
86 #region 实现IEnumerator接口中的方法
87 public object Current
88 {
89 get
90 {
91 return this.current;
92 }
93 }
94
95 public bool MoveNext()
96 {
97 if (index + 1 > friends.Count)
98 {
99 return false;
100 }
101 else
102 {
103 this.current = friends[index];
104 index++;
105 return true;
106 }
107 }
108
109 public void Reset()
110 {
111 index = 0;
112 }
113
114 #endregion
115 }
116 }
三、C#2.0中实现迭代器
1 namespace 简化迭代器的实现
2 {
3 class Program
4 {
5 static void Main(string[] args)
6 {
7 Friends friendcollection = new Friends();
8 foreach (Friend f in friendcollection)
9 {
10 Console.WriteLine(f.Name);
11 }
12
13 Console.Read();
14 }
15 }
16
17 /// <summary>
18 /// 朋友类
19 /// </summary>
20 public class Friend
21 {
22 private string name;
23 public string Name
24 {
25 get { return name; }
26 set { name = value; }
27 }
28 public Friend(string name)
29 {
30 this.name = name;
31 }
32 }
33
34 /// <summary>
35 /// 朋友集合
36 /// </summary>
37 public class Friends : IEnumerable
38 {
39 private Friend[] friendarray;
40
41 public Friends()
42 {
43 friendarray = new Friend[]
44 {
45 new Friend("张三"),
46 new Friend("李四"),
47 new Friend("王五")
48 };
49 }
50
51 // 索引器
52 public Friend this[int index]
53 {
54 get { return friendarray[index]; }
55 }
56
57 public int Count
58 {
59 get { return friendarray.Length; }
60 }
61
62 // C# 2.0中简化迭代器的实现
63 public IEnumerator GetEnumerator()
64 {
65 for (int index = 0; index < friendarray.Length; index++)
66 {
67 // 这样就不需要额外定义一个FriendIterator迭代器来实现IEnumerator
68 // 在C# 2.0中只需要使用下面语句就可以实现一个迭代器
69 yield return friendarray[index];
70 }
71 }
72 }
73 }
在上面代码中有一个yield return 语句,这个语句的作用就是告诉编译器GetEnumerator方法不是一个普通的方法,而是实现一个迭代器的方法。
当编译器看到yield return语句时,编译器知道需要实现一个迭代器,所以编译器生成中间代码时为我们生成了一个实现IEnumerator接口的内部类。
大家可以通过Reflector工具进行查看,下面是通过Reflector工具得到一张截图:

四、迭代器执行过程

注:本文参考http://www.cnblogs.com/zhili/archive/2012/12/02/Interator.html
C#基础知识---迭代器与Foreach语句的更多相关文章
- C#基础知识 yield与foreach
什么时候可以使用yield的关键字来定义迭代器? 迭代器的返回类型必须是IEnumerable.IEnumerable<T>.IEnumerator 或 IEnumerator<T& ...
- PHP基础知识之————PDO预处理语句
转载处:http://www.cnblogs.com/xiaohuochai/p/6133353.html 定义 在生成网页时,许多PHP脚本通常都会执行除参数之外,其他部分完全相同的查询语句,针对这 ...
- python基础知识---迭代器、生成器、装饰器
一.迭代器 二.生成器 http://www.cnblogs.com/huxi/archive/2011/07/14/2106863.html def func(): #定义生成器,和普通函数的区别是 ...
- 1.17 Python基础知识 - 迭代器和生成器初识
可循环迭代的对象称为可迭代对象,迭代器和生成器函数是可迭代对象. 列表解析表达式:可以简单高效处理一个可迭代对象,并生成结果列表 示例代码: [ i ** 2 for i in range(10) ] ...
- C# 篇基础知识11——泛型和集合
.NET提供了一级功能强大的集合类,实现了多种不同类型的集合,可以根据实际用途选择恰当的集合类型. 除了数组 Array 类定义在System 命名空间中外,其他的集合类都定义在System.Coll ...
- MySQL数据库基础知识及优化
MySQL数据库基础知识及优化必会的知识点,你掌握了多少? 推荐阅读: 这些必会的计算机网络知识点你都掌握了吗 关于数据库事务和锁的必会知识点,你掌握了多少? 关于数据库索引,必须掌握的知识点 目录 ...
- 第4章 基础知识进阶 第4.1节 Python基础概念之迭代、可迭代对象、迭代器
第四章 基础知识进阶第十七节 迭代.可迭代对象.迭代器 一. 引言 本来计划讲完元组和字典后就讲列表解析和字典解析,但要理解列表解析和字典解析,就需要掌握Python的高级的类型迭代器,因此本节 ...
- C#中foreach语句的迭代器实现机制
C#中的foreach语句可用于循环遍历某个集合中的元素,而所有的只要支持了IEnumerable或IEnumerable<T>泛型接口的类型都是可以 用foreach遍历的.其具体的遍历 ...
- 常见SQL语句和SQL基础知识
引自:http://blog.csdn.net/u012467492/article/details/46790205 SQL语句考察(一) 1.查询出每门课都大于80 分的学生姓名 name k ...
随机推荐
- C语言:模拟密码输入显示星号
一个安全的程序在用户输入密码时不应该显示密码本身,而应该回显星号或者点号,例如······或******,这在网页.PC软件.ATM机.POS机上经常看到.但是C语言没有提供类似的功能,控制台上只能原 ...
- 高校表白App-团队冲刺第九天
今天要做什么 在Fragment首页加上轮转播报,点击图片进入相应连接 做了什么 功能实现,通过连接第三方库来进行实现,比较简单.(url就可以) 遇到的问题 在调用以前的工具类时,有点小问题,发现以 ...
- UI自动化学习笔记- PO模型介绍和使用
一.PO模型 1.PO介绍:page(页面) object(对象) 在自动化中,Selenium 自动化测试中有一个名字经常被提及 PageObject (思想与面向对象的特征相同),通常PO 模型可 ...
- python项目案例
python项目案例1:----此学习案例用python3编写,摘自明日科技,感谢! 学生管理系统: 功能描述:具有增删改查,排序,保存并显示学生的全部信息. 1.主界面---函数menu(),显示功 ...
- 添加数据时报错:An error occurred while updating the entries. See the inner exception for detail。
场景:前几天在项目开发时,有个bug经常出现,今天花了一整天,终于把它解决了.记录一下解决流程. 解决方法: 主要报错的地方在添加的部分: 1 foreach (var requestProperty ...
- vue使用GraphVis开发无限拓展的关系图谱
1.去GraphVis官网下载对应的js,新版和旧版的js有所不同,看自己需求引入旧版还是新版(GraphVis官方网址:http://www.graphvis.cn/) visgraph.min.j ...
- 某学院m3u8视频解密获取分析实战分享
[免责声明]本文来源于作者个人学习整理,仅供学习交流使用,不构成商业目的.所有资源均系本人个人学习或网络收集,仅提供一个展示.介绍.观摩学习的博文,不对其内容的准确性.可靠性.正当性.安全性.合法性等 ...
- SQL Server 判断表名称、索引、表字段是否存在
1.判断索引是否存在 ps:@tableName 表名称, @indexName 索引名 IF EXISTS (SELECT 1 FROM sys.indexes WHERE object_id=OB ...
- 【开源】这可能是封装微信 API 最全的 .NET SDK 了
## 缘起 今年公司某个项目需要全面接入微信支付 V3 版 API.起初觉得,2014 年微信支付就已上线了 V3 版 API,这都 2021 年了,就算官方不给力,怎么着社区也该有几个造好的 .NE ...
- Linux-shell编程经验记录
Linux-shell编程经验总结 1.接收用户输入 #读取用户输入并且将输入保存到input变量中 read -p "请输入:" input #也可以先输出信息再进行读取,这里的 ...