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将数据传 ...
随机推荐
- SVG :可缩放矢量图形(Scalable Vector Graphics)。
SVG 意为可缩放矢量图形(Scalable Vector Graphics). SVG 使用 XML 格式定义图像. SVG 图像在放大或改变尺寸的情况下其图形质量不会有所损失 SVG 使用 XML ...
- Windows下如何查看当前登录用户
1.通过whoami命令查看 2.通过username变量查看,具体命令如下:echo %username% 上述两种方法只能查看当前会话用户信息,那么如何看到其他登录用户呢? 可以通过执行query ...
- Windows TAKEOWN & ICACLS
TAKEOWN:takeown /f 文件名 获取该文件的所属权takeown /f /r /d n 文件夹 获取整个文件夹及其下面子目录文件的所属权 TAK ...
- vux 实现多栏滚动
1.PopupPicker 组件 <!-- vux-ui --> <template> <div> <!-- 标题栏 --> <x-header ...
- keepalived + lvs 网站高可用集群
一 ,四台服务器 master 端 : 192.168.1.3 backup 端: 192.168.1.4 REserver1 端 : 192.168.1.5 REserver2 端: 192.168 ...
- WPF自学入门(十一)WPF MVVM模式Command命令 WPF自学入门(十)WPF MVVM简单介绍
WPF自学入门(十一)WPF MVVM模式Command命令 在WPF自学入门(十)WPF MVVM简单介绍中的示例似乎运行起来没有什么问题,也可以进行更新.但是这并不是我们使用MVVM的正确方式 ...
- 8.跟我学solr---UpdateRequestProcessor具体解释
简单介绍 java web开发的同学应该非常熟悉,在开发中常常会使用filter来处理请求中的一些切面需求. solr也提供类似的一种链式结构的handler来满足在加入数据索引请求的时候.通过切片的 ...
- ios Enum Value To NSString
#define enumToString(value) @#value eg. typedef NS_ENUM(NSInteger, Sex) { Male = 0, Famale = 1, }; ...
- Codeforces(429D - Tricky Function)近期点对问题
D. Tricky Function time limit per test 2 seconds memory limit per test 256 megabytes input standard ...
- VC++ 模拟"CLICK事件"关闭指定窗体
今天改动一个工具时遇到一个有意思的问题,打开某个窗体时弹出一些不相关的窗体.须要用户自己去手动点击后才干继续.保证不了自己主动处理,如今解说决方案记录一下,例如以下 主要使用windows提供的Fin ...