C#知识点-枚举器和迭代器
一、几个基本概念的理解
问题一:为什么数组可以使用foreach输出各元素
答:数组是可枚举类型,它实现了一个枚举器(enumerator)对象;枚举器知道各元素的次序并跟踪它们的位置,然后返回请求的当前项
问题二:不用foreach能不能遍历各元素

问题三:什么是可枚举类
答:可枚举类是指实现了IEnumerable接口的类;IEnumerable接口只有一个成员GetEnumerator方法,它返回对象的枚举器
问题四:什么是枚举器
答:实现了IEnumerator接口的枚举器包含三个函数成员:Current,MoveNext,Reset
Current是只读属性,它返回object类型的引用;
MoveNext是把枚举器位置前进到集合的下一项的方法,它返回布尔值,指示新的位置是否有效位置还是已经超过了序列的尾部;
Reset是把位置重置为原始状态的方法;
二、下面代码展示了一个可枚举类的完整示例
1 namespace ConsoleApplication4
2 {
3 /// <summary>
4 /// 自定义一个枚举对象
5 /// </summary>
6 class ColorEnumerator : IEnumerator
7 {
8 private string[] _colors;
9 private int _position = -1;
10
11 public ColorEnumerator(string[] arr)
12 {
13 _colors = arr;
14 for (int i = 0; i < arr.Length; i++)
15 {
16 _colors[i] = arr[i];
17 }
18 }
19 public object Current
20 {
21 get
22 {
23 if (_position == -1)
24 {
25 throw new InvalidOperationException();
26 }
27 if (_position >= _colors.Length)
28 {
29 throw new InvalidOperationException();
30 }
31 return _colors[_position];
32 }
33 }
34
35 public bool MoveNext()
36 {
37 if (_position < _colors.Length - 1)
38 {
39 _position++;
40 return true;
41 }
42 else
43 {
44 return false;
45 }
46 }
47
48 public void Reset()
49 {
50 _position = -1;
51 }
52 }
53
54 /// <summary>
55 /// 创建一个实现IEnumerable接口的枚举类
56 /// </summary>
57 class Spectrum : IEnumerable
58 {
59 private string[] Colors = { "red", "yellow", "blue" };
60 public IEnumerator GetEnumerator()
61 {
62 return new ColorEnumerator(Colors);
63 }
64 }
65
66 class Program
67 {
68 static void Main(string[] args)
69 {
70 Spectrum spectrum = new Spectrum();
71 foreach (string color in spectrum)
72 {
73 Console.WriteLine(color);
74 }
75 Console.ReadKey();
76 }
77 }
78 }
79
三、泛型枚举接口
IEnumerable<T>接口的GetEnumerator方法返回实现IEnumerator<T>的枚举类的实例;
实现IEnumerator<T>的类实现了Current属性,它返回实际类型的对象,而不是object基类的引用;
所以非泛型接口的实现不是类型安全的,因为还需要转换为实际类型。
四、迭代器
1.使用迭代器来创建枚举器
1 namespace ConsoleApplication5
2 {
3 class MyClass
4 {
5 /// <summary>
6 /// 获取一个迭代器
7 /// </summary>
8 /// <returns></returns>
9 public IEnumerator<string> GetEnumerator()
10 {
11 return ColorEnumerator();
12 }
13 /// <summary>
14 /// 迭代器
15 /// </summary>
16 /// <returns></returns>
17 public IEnumerator<string> ColorEnumerator()
18 {
19 yield return "red";
20 yield return "yellow";
21 yield return "blue";
22 }
23 }
24 class Program
25 {
26 static void Main(string[] args)
27 {
28 MyClass mc = new MyClass();
29 foreach (string color in mc)
30 {
31 Console.WriteLine(color);
32 }
33 Console.ReadKey();
34 }
35 }
36 }
2.使用迭代器来创建枚举类型
1 namespace ConsoleApplication6
2 {
3 class MyClass
4 {
5 public IEnumerator<string> GetEnumerator()
6 {
7 //获取可枚举类型
8 IEnumerable<string> enumerable = ColorEnumerable();
9 //获取枚举器
10 return ColorEnumerable().GetEnumerator();
11 }
12
13 public IEnumerable<string> ColorEnumerable()
14 {
15 yield return "red";
16 yield return "yellow";
17 yield return "blue";
18 }
19 }
20 class Program
21 {
22 static void Main(string[] args)
23 {
24 MyClass mc = new MyClass();
25 //使用类对象
26 foreach (string color in mc)
27 {
28 Console.WriteLine(color);
29 }
30 Console.WriteLine("-----------------------");
31 //使用类枚举器的方法
32 foreach (string color in mc.ColorEnumerable())
33 {
34 Console.WriteLine(color);
35 }
36 Console.ReadKey();
37 }
38 }
39 }
3.产生多个可迭代类型
1 namespace ConsoleApplication7
2 {
3 class MyClass
4 {
5 private string[] Colors = { "red", "yellow", "blue" };
6 //顺序
7 public IEnumerable<string> ColorOrder()
8 {
9 for (int i = 0; i < Colors.Length; i++)
10 {
11 yield return Colors[i];
12 }
13 }
14 //逆序
15 public IEnumerable<string> ColorReversed()
16 {
17 for (int i = Colors.Length - 1; i >= 0; i--)
18 {
19 yield return Colors[i];
20 }
21 }
22 }
23 class Program
24 {
25 static void Main(string[] args)
26 {
27 MyClass mc = new MyClass();
28 foreach (string color in mc.ColorOrder())
29 {
30 Console.WriteLine(color);
31 }
32 Console.WriteLine("------------------");
33 foreach (string color in mc.ColorReversed())
34 {
35 Console.WriteLine(color);
36 }
37 Console.ReadKey();
38 }
39 }
40 }
41
C#知识点-枚举器和迭代器的更多相关文章
- C#图解教程 第十八章 枚举器和迭代器
枚举器和迭代器 枚举器和可枚举类型 foreach语句 IEnumerator接口 使用IEnumerable和IEnumerator的示例 泛型枚举接口迭代器 迭代器块使用迭代器来创建枚举器使用迭代 ...
- C# 枚举器和迭代器
一.枚举器(enumerator)和可枚举类型(enumeration) 我们都知道foreach语句可以用来遍历数组中的元素,但你有没有想过为什么它可以被foreach处理呢? 这是因为数组可以按需 ...
- 设计模式 - 适配器模式(adapter pattern) 枚举器和迭代器 具体解释
适配器模式(adapter pattern) 枚举器和迭代器 具体解释 本文地址: http://blog.csdn.net/caroline_wendy 參考适配器模式(adapter patter ...
- C#-14 枚举器和迭代器
一 枚举器和可枚举类型 当我们为数组使用foreach语句时,这个语句为我们依次取出了数组中的每一个元素. var arrInt = new int[] { 11, 12, 13, 14 }; for ...
- 【Unity|C#】基础篇(20)——枚举器与迭代器(IEnumerable/IEnumerator)
[学习资料] <C#图解教程>(第18章):https://www.cnblogs.com/moonache/p/7687551.html 电子书下载:https://pan.baidu. ...
- C#枚举器/迭代器
一.枚举器 1.为什么foreach可以顺序遍历数组? 因为foreach可以识别可枚举类型,通过访问数组提供的枚举器对象来识别数组中元素的位置从而获取元素的值并打印出来. 2.什么是枚举器?可枚举类 ...
- C#中的枚举器(转)
术语表 Iterator:枚举器(迭代器) 如果你正在创建一个表现和行为都类似于集合的类,允许类的用户使用foreach语句对集合中的成员进行枚举将会是很方便的.这在C# 2.0中比 C# 1.1更容 ...
- ruby迭代器枚举器
迭代器一个迭代器是一个方法,这个方法里面有yield语句,使用了yield的方法叫做迭代器,迭代器并非一定要迭代,与传递给这个方法的块进行数据传输 yield将数据传给代码快,代码块再把数据传输给yi ...
- ruby中迭代器枚举器的理解
参考<ruby编程语言>5.3迭代器和可枚举对象 迭代器一个迭代器是一个方法,这个方法里面有yield语句,这个方法里的yield语句,与传递给这个方法的块进行数据传输 yield将数据传 ...
随机推荐
- Java 读取Excel内容并保存进数据库
读取Excel中内容,并保存进数据库 步骤 建立数据库连接 读取文件内容 (fileInputStream 放进POI的对应Excel读取接口,实现Excel文件读取) 获取文件各种内容(总列数,总行 ...
- 安装adt-bundle-windows-x86-20130917时遇到的问题及解决方法
最近在上安卓课,老师让我们下载此软件(adt-bundle-windows-x86-20130917.下载压缩后,打开eclipse的时候,会出现以下情况: 这时说明你的jdk还没下载或者下载错位置了 ...
- Java电商项目-5.内容管理cms系统
目录 实现加载内容分类树功能 实现内容分类动态添加 删除内容分类节点 实现内容分类节点的分页显示 实现广告内容的添加 实现广告内容删除 实现广告内容编辑 到Github获取源码请点击此处 实现加载内容 ...
- easyui webuploader 文件上传演示
webuploader 上传首页 webuploader 上传前页面 webuploader 上传中页面 图就不上传了,状态会编程上传中 webuploader 已上传页面
- 一步步搭建java信息管理系统00 - 前言
开发前,先上效果图吧 信息管理系统,个人认为,以下几个因素是不可缺少的 多tab 因菜单比较多,右侧的树形一定要考虑,如果菜单还是多,那么顶部就要考虑起来了 以后想到什么,再添加吧. 看到easyui ...
- 实战c++中的vector系列--emplace_back造成的引用失效
上篇将了对于struct或是class为何emplace_back要优越于push_back,可是另一些细节没有提及.今天就谈一谈emplace_back造成的引用失效. 直接撸代码了: #inclu ...
- form 表单序列化 serialize
在开发中有时需要在js中提交form表单数据,就需要将form表单进行序列化. jquery提供的serialize方法能够实现. $("#searchForm").seriali ...
- 数学之路-python计算实战(21)-机器视觉-拉普拉斯线性滤波
拉普拉斯线性滤波,.边缘检測 . When ksize == 1 , the Laplacian is computed by filtering the image with the follow ...
- HttpURL连接远程serverGet和Post方式请求并返回数据
查看原文:http://www.ibloger.net/article/1813.html package cn.gis; import java.io.BufferedReader; import ...
- ubuntu双网卡绑定配置
1,安装bonding需要的软件 sudo apt-get install ifenslave 2,在/etc/modules中加入: bonding mode= miimon= 3,在/etc/ne ...