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将数据传 ...
随机推荐
- Servlet开发(3)
Servlet开发 Servlet过滤器: 主要是对访问主页的用户进行过滤,通过登录系统进入的用户可以看到主页内容,在session中存在currentuser. 可以对此进行判断: package ...
- Evaluate Reverse Polish Notation(逆波兰式)
Evaluate the value of an arithmetic expression in Reverse Polish Notation. Valid operators are +, -, ...
- mysql-performance-schema
http://www.fromdual.com/mysql-performance-schema-hints http://www.cnblogs.com/cchust/
- mysql的时间戳说白了就俩问题,自动更新问题和不自动更新问题
mysql的时间戳timestamp说白了就俩问题,自动更新问题和不自动更新问题
- weblogic自带的jdk是在工程的包部署后编译使用
weblogic自带的jdk是在工程的包部署后编译使用的.当用户把项目打包部署到weblogic上面,运行该项目的java环境jdk就是用的weblogic自带的jdk了,工程中的jdk和编译时的jd ...
- android_handler(二)
这篇记录 android 消息机制中.WorkThread 模拟向网络訪问数据,获得数据后,返回 message 发送给 MainThread ,并改动 TextView 的 text 的这种一个步骤 ...
- 神马都是浮云,unity中自己写Coroutine协程源代码
孙广东 2014.7.19 无意之间看到了,Unity维基上的一篇文章, 是关于自己写协程的介绍. 认为非常好,这样能更好的了解到协程的执行机制等特性.还是不错的. 原文链接地址例如以下: ht ...
- java创建线程的三种方式及其对照
Java中创建线程主要有三种方式: 一.继承Thread类创建线程类 (1)定义Thread类的子类.并重写该类的run方法,该run方法的方法体就代表了线程要完毕的任务.因此把run()方法称为运行 ...
- java后台修改ZK页面的title
Clients.evalJavaScript("document.title='"+basicDBObject.getString("systemName")+ ...
- CSS和JS结合控制样式
CSS控制样式,毋庸置疑.但有时,仅靠CSS却很难控制好,比如说,页面在多种条件下进行不同的呈现:或者运行过程中,会发生变化,比如说,左侧的菜单栏收缩了,那么右侧的宽度就变大了. 就拿这个元素的wid ...