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 ...
随机推荐
- python05篇 json和函数
一.json json就是一个字符串,只不过是所有语言能解析这个字符串.1.1 把python的数据类型转为json import json d = {'name': 'xiaohei', 'cars ...
- Django基础-003 配置Django自带的后台管理,操作数据库
插入测试数据,可以自己写页面来插入数据 也可以使用Django自带的后台管理,来操作数据表 1.创建用户 python manage.py createsuperuser 2.在浏览器输入地址,进入D ...
- Python基础之动态添加属性,方法,动态类,静态类
## 动态添加属性class Person: def __init__(self,name): self.name = name# 1.通过对象.属性名称来操作p = Person('KTModel' ...
- 【LeetCode】404. 左叶子之和
404. 左叶子之和 知识点:二叉树 题目描述 计算给定二叉树的所有左叶子之和.. 示例 3 / \ 9 20 / \ 15 7 在这个二叉树中,有两个左叶子,分别是 9 和 15,所以返回 24 解 ...
- intouch 趋势图Y轴自适应功能完善
在项目中有利用到历史趋势,其y轴往往展示的是该点的最小/最大值范围,对于曲线波动展示不够友好.故而利用自带方法进行完善,以此记录. Histrend1.MinRange=HTGetAutoScaleV ...
- Go语言常见的坑
目录 1. 可变参数是空接口类型 2. 数组是值传递 3.map遍历是顺序不固定 4. 返回值被屏蔽 5.recover必须在defer函数中运行 6. main函数提前退出 7.通过Sleep来回避 ...
- 开机时自动启动的AutoHotkey脚本 2019年07月08日19时06分
;;; 开机时自动启动的AutoHotkey脚本;; 此脚本修改时间 2019年06月18日20时48分;; 计时器创建代码段 ------------------------------------ ...
- Python RPC 不会?不妨看看这篇文章
1. 前言 大家好,我是安果! RPC,全程为 Remote Procedure Call,是一种进程间的通信方式,它采用「 服务端 / 客户机 」模式,是一种请求响应模型 其中,服务端负责提供服务程 ...
- noip模拟测试30
考试总结:这次考试,不是很顺利,首先看了一眼题目,觉得先做T1,想了一会觉得没什么好思路,就去打暴力,结果我不会枚举子集,码了半天发现不对,就随便交了一份代码上去,结果CE了,然后去打T3,20min ...
- Java数组07——稀疏数组
稀疏数组 总结: 记录有效的坐标: 记录原始做表的大小和有效值的个数 记录每一个有效值的坐标 ,变成一个新的数组 age: package array; public class ArrayDe ...