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将数据传 ...
随机推荐
- XJTUOJ13 (数论+FFT)
http://oj.xjtuacm.com/problem/13/ 题意:wmq如今开始学习乘法了!他为了训练自己的乘法计算能力,写出了n个整数, 并且对每两个数a,b都求出了它们的乘积a×b.现在他 ...
- Linux系统备份还原工具1(DD)(应用实例)
DD使用教程:http://www.cnblogs.com/EasonJim/p/7442223.html 以下实例没经过大量测试,可能在一些机器上不会有效. 一般围绕以下几点进行设置: 1.dd完后 ...
- 怎么让Excel显示时间时候能把秒显示出来
Excel显示时间一般只显示年月日小时分钟怎么能够把秒也显示出来既如下显示 2007-04-11 12:00:00 将单元格格式设为"自定义",在"类型"框中输 ...
- 【CV论文阅读】Detecting events and key actors in multi-person videos
论文主要介绍一种多人协作的视频事件识别的方法,使用attention模型+RNN网络,最近粗浅地学习了RNN网络,它比较适合用于处理序列的存在上下文作用的数据. NCAA Basketball数据集 ...
- 手动加入SSH支持、使用c3p0
之前做的笔记,如今整理一下.大家有耐心的跟着做就能成功: SSH(struts2.spring.hibernate) * struts2 * 充当mvc的角色 * hibernate ...
- matlab Newton method
% Matlab script to illustrate Newton's method % to solve a nonlinear equation % this particular scri ...
- android 特殊符号开头的联系人归并至“#”下
在PeopleActivity界面.联系人的显示位置是由其display name的第一个字符决定的. 数字开头的联系人会显示在"#"这个header下. 中英文联系人会显示在&q ...
- nginx负载均衡向后台传递參数方法(后端也是nginxserver)
做了一个站点是用nginx 做的负载均衡.后端也是多个nginxserver 遇到了一个问题.当做SSL支持时 前端nginx分发到 后端nginx后就成 http形式了(这样后台php用$_SERV ...
- [swift实战入门]手把手教你编写2048(一)
苹果设备越来越普及,拿着个手机就想捣鼓点啥,于是乎就有了这个系列,会一步一步教大家学习swift编程,学会自己做一个自己的app,github地址:https://github.com/scarlet ...
- java.io.IOException: read failed, socket might closed or timeout, read ret: -1
近期项目中连接蓝牙之后接收蓝牙设备发出的指令功能,在连接设备之后,创建RfcommSocket连接时候报java.io.IOException: read failed, socket might c ...