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语言:宏完美定义
#include <stdio.h> #define M (n*n+3*n) #define M1 n*n+3*n int main(){ int sum, n; printf(" ...
- Java基础00-修饰符18
1. 包 1.1 包的概述和使用 通过记事本的方法 package com.itheima;public class HelloWorld { public static void main(Stri ...
- ES6 Class类
在ES6中,class (类)作为对象的模板被引入,可以通过 class 关键字定义类.class 的本质是 function.它可以看作一个语法糖,让对象原型的写法更加清晰.更像面向对象编程的语法类 ...
- 算法leetcode_分治算法
一.基本概念 在计算机科学中,分治法是一种很重要的算法.字面上的解释是"分而治之",就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题--直到最后子 ...
- kafka可视化工具
Kafka可视化客户端工具(Kafka Tool 2)的安装和使用 Kafka Tool 2 是一款 Kafka 的可视化客户端工具,可以非常方便的查看 Topic 的队列信息.消费者信息以及 kaf ...
- GC垃圾回收机制详解
JVM堆相关知识 为什么先说JVM堆? JVM的堆是Java对象的活动空间,程序中的类的对象从中分配空间,其存储着正在运行着的应用程序用到的所有对象.这些对象的建立方式就是那些new一类的操作 ...
- etcd学习(4)-centos7中部署etcd
etcd的搭建 前言 单机 集群 创建etcd配置文件 更新etcd系统默认配置 启动 配置ETCD为启动服务 测试下 参考 etcd的搭建 前言 这里记录下如何搭建etcd 单机 在etcd的rel ...
- mapGetters 的作用__为什么mapGetter前面有...(三个点是去掉{}的作用)
参考:vuex 中关于 mapGetters 的作用 mapGetters 工具函数会将 store 中的 getter 映射到局部计算属性中.它的功能和 mapState 非常类似,我们来直接看它的 ...
- mysql采坑笔记
mysqld --initialize-insecure // 初始化数据 mysql -u root -p // 登录 navicat for mysql 1251错误解决方法 ALTER USER ...
- Thinkphp 生成的验证码不显示问题解决
在调用验证码之前加上 ob_clean(); 将: public function verify(){ $verify = new \Think\Verify(); ...