Net面向对象程序设计-19-枚举集合-2010-2011-2.ppt

上传人:本田雅阁 文档编号:2202242 上传时间:2019-03-03 格式:PPT 页数:28 大小:889.01KB
返回 下载 相关 举报
Net面向对象程序设计-19-枚举集合-2010-2011-2.ppt_第1页
第1页 / 共28页
Net面向对象程序设计-19-枚举集合-2010-2011-2.ppt_第2页
第2页 / 共28页
Net面向对象程序设计-19-枚举集合-2010-2011-2.ppt_第3页
第3页 / 共28页
亲,该文档总共28页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述

《Net面向对象程序设计-19-枚举集合-2010-2011-2.ppt》由会员分享,可在线阅读,更多相关《Net面向对象程序设计-19-枚举集合-2010-2011-2.ppt(28页珍藏版)》请在三一文库上搜索。

1、,.NET面向对象程序设计 第19章 枚举集合,19.1枚举集合中的元素,foreach语句极大的简化了需要编写的代码 int pins = 9, 3, 7, 2 ; foreach (int pin in pins) Console.WriteLine(pin); 为什么数组可以这么做呢? 数组可以按需提供一个叫做枚举器的对象,枚举器可以依次返回请求的数组的元素 枚举器指导项的次序并且跟踪它在序列中的位置,然后返回请求的当前项,对于枚举器的类型而言,必须有一个方法来获取它们 在.net中获取一个对象枚举器的标准方法是调用对象的GetEnumerator方法 凡是实现了GetEnumerato

2、r方法的类型叫做可枚举类型enumerable,可枚举的集合:实现了System.Collections .IEnumerable接口的一个集合 C#中所有数组都是System.Array类的实例 该类是实现了IEnumerable接口的一个集合类 在IEnumerable接口中,包含一个名为GetEnumerator的方法: IEnumerator GetEnumerator();,GetEnumerator方法返回一个枚举器对象,该枚举器实现了System.Collections .IEnumerable接口 枚举器对象用于遍历集合中的元素 IEnumerator接口指定了以下方法和属性:

3、 object Current get; bool MoveNext(); void Reset();,foreach结构被设计用来和可枚举类型一起使用,只要给他的遍历对象是可枚举类型,比如数组,它会执行以下操作: 通过调用GetEnumerator方法获取对象的枚举器 从枚举器中请求每一项并且把它作为迭代变量,枚举器类型,枚举器一共有三种,工作原理相同,但有一些细小的区别 IEnumerator/IEnumerable接口非泛型接口形式 IEnumerator/IEnumerable接口泛型接口形式 不使用接口形式,2、使用IEnumerator 接口,IEnumerator接口包含三个函数

4、成员:Current、MoveNext以及Reset。 Current返回序列中当前位置项的属性。 它是只读属性。 它返回object类型的引用,所以可以返回任何类型。 MoveNext是把枚举数位置前进到集合中下一项的方法。它也返回布尔值,指示新的位置是有效位置或已经超过了序列的尾部。 如果新的位置是有效的,方法返回true。 如果新的位置是无效的(比如到达了尾部),方法返回false 枚举数的原始位置在序列中的第一项之前。MoveNext必须在第一次使用Current之前使用,否则CLR会抛出一个InvalidOperationException异常。 Reset方法把位置重置为原始状态。

5、,枚举数类通常被声明为类中的嵌套类,枚举数与序列中的当前项保持联系的方式完全取决于实现。可以通过对象引用、索引值或其他方式来实现。对于数组来说,就使用项的索引。,有了集合的枚举数,我们就可以使用MoveNext和Current成员来模仿foreach循环遍历集合中的项。 例如数组就是可枚举类型,所以下面的代码手动做foreach语句自动做的事情。输出和使用foreach循环的输出一样。,要创建非泛型接口的枚举数类,必须声明实现IEnumerator接口的类。 IEnumerator接口有如下的特性: 它是System.Collection命名空间的成员。 它包含三个方法Current、Move

6、Next和Reset。,非泛型枚举数类的框架,示例:实现一个列出颜色名数组的枚举类型,3、IEnumerable 接口,IEnumerable接口只有一个成员GetEnumerator方法,它返回对象的枚举数。,使用IEnumerable 和IEnumerator 的示例,4、不实现接口的枚举数,使用IEnumerable和IEnumerator接口可以创建可枚举类型和枚举数,但是这种方法有几个缺点: 首先,由Current返回的对象是object类型的。对于值类型而言,在由Current返回之前必须装箱成object。在从Current获取之后,又必须再一次拆箱。如果需要操作大量的数据,会带

7、来严重的性能问题。 非泛型接口方法的另外一个缺点是失去了类型安全。值被作为对象来枚举,所以可以是任何类型。这就消除了编译时的类型检测,解决方法: 对于枚举数类: 不要继承自IEnumerator。 像以前一样实现MoveNext。 像以前一样实现Current,把返回类型设置为和枚举的项一样。 不需要实现Reset。 对于可枚举类: 不要继承自IEnumerable。 像以前一样实现GetEnumerator,设置返回值为枚举数类。,比较基于接口的和非基于接口的枚举数,5、泛型枚举接口,第三种形式的枚举数是使用泛型接口IEnumerable和IEnumerator。 对于非泛型接口形式: IE

8、numerable接口的GetEnumerator方法返回实现IEnumerator枚举数类的实例。 实现IEnumerator的类实现了Current属性,它返回object的引用,我们必须把它转化为实际类型的对象。 对于泛型接口形式: IEnumerable接口的GetEnumerator方法返回实现IEnumator的枚举数类的实例。 实现IEnumerator的类实现了Current属性,它返回实际类型的对象,而不是object基类的引用。,6、IEnumerator接口,IEnumerator接口使用泛型来返回实际的类型,而不是object类型的对象。 IEnumerator接口从另

9、外两个接口继承非泛型IEnumerable接口和IDisposable接口。所以,它肯定实现了它们的成员。 IEnumerator接口本身只有一个Current方法,它返回衍生类型的项不是object类型的项。 由于IEnumerator和IEnumerator都有一个叫做Current的成员,我们应该显式实现IEnumerator版本,然后在类中实现泛型版本,如下代码使用泛型枚举数接口来实现ColorEnumerator实例,7、IEnumerable接口,泛型IEnumerable 接口与IEnumerable 的非泛型版本很相似。 泛型版本从IEnumerable继承,所以也必须实现IE

10、numerable接口。,如下代码演示了泛型可枚举接口的使用:,8、迭代器,为了将一个集合变得“可枚举”,其过程非常复杂 C#从2.0版本开始提供了更简单的创建枚举数和可枚举类型的方式。 编译器会为我们创建它们,这种结构叫做迭代器 迭代器(iterator)是能生成(yield)已排序值序列的一个代码块 注意:iterator实际并不是一个可枚举类的成员,相反,它只是指定了一个序列,枚举器应该用这个序列来返回其中的值 即,迭代器只是对枚举序列的一个描述,C#编译器可以利用它来创建自己的枚举器,19.2.1 一个简单的迭代器,using System;using System.Collectio

11、ns.Generic;using System.Collections; class BasicCollection : IEnumerable private List data = new List(); public void FillList(params T items) foreach (var datum in items) data.Add(datum); IEnumerator IEnumerable.GetEnumerator() foreach (var datum in data) yield return datum; IEnumerator IEnumerable.

12、GetEnumerator() / Not implemented in this example ,BasicCollection bc = new BasicCollection(); bc.FillList(“Twas“, “brillig“, “and“, “the“, “slithy“, “toves“); foreach (string word in bc) Console.WriteLine(word);,迭代器块是有一个或多个yield语句的代码块。下面三种类型的代码块中的任意一种都可以是迭代器块: 方法主体 访问器主体 运算符主体 迭代器块被认为与其他代码块不同。 其他块包

13、含的语句被当作是命令式的。即,代码块的第一个语句被执行然后是后面的语句,最后控制离开块。 迭代器块不是需要在同一时间执行的一序列命令式语句,而是描述了希望编译器为我们创建的枚举数类的行为。 迭代器块中的代码描述了如何枚举元素。,迭代器返回一个泛型枚举数,该枚举数返回三个string类型的项。 yield return语句声明这是枚举中的下一项。 迭代器块有两个特殊语句: yield return;返回集合的一个元素,并移动到下一个元素上 。 yield break语句指定在序列中没有更多项。,IListFindBobs(IEnumerable names) var bobs = new Lis

14、t(); foreach(var currName in names) if(currName = “Bob“) bobs.Add(currName); return bobs; ,IEnumerable FindBobs(IEnumerable names) foreach(var currName in names) if(currName = “Bob“) yield return currName; ,传统的执行方法 1.调用函数 2.函数执行并返回list 3.调用部分使用返回的list,Yield的执行方法 1.调用函数 2.调用者请求item 3.下一个item返回 4.回到步骤2,使用迭代器来创建枚举数,

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 其他


经营许可证编号:宁ICP备18001539号-1