Net面向对象程序设计-19-枚举集合.ppt_第1页
Net面向对象程序设计-19-枚举集合.ppt_第2页
Net面向对象程序设计-19-枚举集合.ppt_第3页
Net面向对象程序设计-19-枚举集合.ppt_第4页
Net面向对象程序设计-19-枚举集合.ppt_第5页
已阅读5页,还剩23页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

.NET面向对象程序设计 第19章 枚举集合 19.1枚举集合中的元素 foreach语句极大的简化了需要编写的代码 int pins = 9, 3, 7, 2 ; foreach (int pin in pins) Console.WriteLine(pin); 为什么数组可以这么做呢? u数组可以按需提供一个叫做枚举器的对象,枚举器 可以依次返回请求的数组的元素 u枚举器指导项的次序并且跟踪它在序列中的位置, 然后返回请求的当前项 对于枚举器的类型而言,必须有一个方法来获取它们 在.net中获取一个对象枚举器的标准方法是调用对象的 GetEnumerator方法 凡是实现了GetEnumerator方法的类型叫做可枚举类型 enumerable 可枚举的集合:实现了System.Collections .IEnumerable接口的一个集合 C#中所有数组都是System.Array类的实例 该类是实现了IEnumerable接口的一个集合类 在IEnumerable接口中,包含一个名为 GetEnumerator的方法: uIEnumerator GetEnumerator(); GetEnumerator方法返回一个枚举器对象,该枚 举器实现了System.Collections .IEnumerable 接口 枚举器对象用于遍历集合中的元素 IEnumerator接口指定了以下方法和属性: uobject Current get; ubool MoveNext(); uvoid Reset(); foreach结构被设计用来和可枚举类型一起使用, 只要给他的遍历对象是可枚举类型,比如数组, 它会执行以下操作: u通过调用GetEnumerator方法获取对象的枚举器 u从枚举器中请求每一项并且把它作为迭代变量 枚举器类型 枚举器一共有三种,工作原理相同,但有一些细 小的区别 uIEnumerator/IEnumerable接口非泛型接口形式 uIEnumerator/IEnumerable接口泛型接口形 式 u不使用接口形式 2、使用IEnumerator 接口 IEnumerator接口包含三个函数成员:Current、 MoveNext以及Reset。 uCurrent返回序列中当前位置项的属性。 l它是只读属性。 l它返回object类型的引用,所以可以返回任何类型。 uMoveNext是把枚举数位置前进到集合中下一项的方法。它也返回 布尔值,指示新的位置是有效位置或已经超过了序列的尾部。 l如果新的位置是有效的,方法返回true。 l如果新的位置是无效的(比如到达了尾部),方法返回false l枚举数的原始位置在序列中的第一项之前。MoveNext必须在 第一次使用Current之前使用,否则CLR会抛出一个 InvalidOperationException异常。 uReset方法把位置重置为原始状态。 枚举数类通常被声明为类中的嵌套类 枚举数与序列中的当前项保持联系的方式完全取决于实现 。可以通过对象引用、索引值或其他方式来实现。对于数 组来说,就使用项的索引。 有了集合的枚举数,我们就可以使用MoveNext和 Current成员来模仿foreach循环遍历集合中的项。 例如数组就是可枚举类型,所以下面的代码手动做 foreach语句自动做的事情。输出和使用foreach循环的输 出一样。 要创建非泛型接口的枚举数类,必须声明实现 IEnumerator接口的类。 IEnumerator接口有如下的特性: u它是System.Collection命名空间的成员。 u它包含三个方法Current、MoveNext和Reset。 非泛型枚举 数类的框架 示例:实现一个列出颜色名数组的枚举类型 3、IEnumerable 接口 IEnumerable接口只有一个成员GetEnumerator 方法,它返回对象的枚举数。 使用IEnumerable 和IEnumerator 的示例 4、不实现接口的枚举数 使用IEnumerable和IEnumerator接口可以创建可 枚举类型和枚举数,但是这种方法有几个缺点: u首先,由Current返回的对象是object类型的。对于值 类型而言,在由Current返回之前必须装箱成object。 在从Current获取之后,又必须再一次拆箱。如果需要 操作大量的数据,会带来严重的性能问题。 u非泛型接口方法的另外一个缺点是失去了类型安全。 值被作为对象来枚举,所以可以是任何类型。这就消 除了编译时的类型检测 解决方法: 对于枚举数类: 不要继承自IEnumerator。 像以前一样实现MoveNext。 像以前一样实现Current,把返回类型设置为和枚举的项一样。 不需要实现Reset。 对于可枚举类: 不要继承自IEnumerable。 像以前一样实现GetEnumerator,设置返回值为枚举数类。 比较基于接口的和非基于接口的枚举数 5、泛型枚举接口 第三种形式的枚举数是使用泛型接口 IEnumerable和IEnumerator。 对于非泛型接口形式: uIEnumerable接口的GetEnumerator方法返回实现 IEnumerator枚举数类的实例。 u实现IEnumerator的类实现了Current属性,它返回 object的引用,我们必须把它转化为实际类型的对象。 对于泛型接口形式: uIEnumerable接口的GetEnumerator方法返回实现 IEnumator的枚举数类的实例。 u实现IEnumerator的类实现了Current属性,它返回 实际类型的对象,而不是object基类的引用。 6、IEnumerator接口 IEnumerator接口使用泛型来返回实际的类型 ,而不是object类型的对象。 IEnumerator接口从另外两个接口继承非 泛型IEnumerable接口和IDisposable接口。所以 ,它肯定实现了它们的成员。 IEnumerator接口本身只有一个Current方法, 它返回衍生类型的项不是object类型的项。 由于IEnumerator和IEnumerator都有一个叫 做Current的成员,我们应该显式实现 IEnumerator版本,然后在类中实现泛型版本 如下代码使用泛型枚举数接口来实现ColorEnumerator实例 7、IEnumerable接口 泛型IEnumerable 接口与IEnumerable 的非 泛型版本很相似。 泛型版本从IEnumerable继承,所以也必须实现 IEnumerable接口。 如下代码演示了泛型可枚举接口的使用: 8、迭代器 为了将一个集合变得“可枚举”,其过程非常复杂 C#从2.0版本开始提供了更简单的创建枚举数和 可枚举类型的方式。 编译器会为我们创建它们,这种结构叫做迭代器 迭代器(iterator)是能生成(yield)已排序值 序列的一个代码块 注意:iterator实际并不是一个可枚举类的成员, 相反,它只是指定了一个序列,枚举器应该用这 个序列来返回其中的值 即,迭代器只是对枚举序列的一个描述,C#编译 器可以利用它来创建自己的枚举器 19.2.1 一个简单的迭代器 using System;using System.Collections.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.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语句的代码块。下 面三种类型的代码块中的任意一种都可以是迭代 器块: u方法主体 u访问器主体 u运算符主体 迭代器块被认为与其他代码块不同。 u其他块包含的语句被当作是命令式的。即,代码块的第一个语句 被执行然后是后面的语句,最后控制离开块。 u迭代器块不是需要在同一时间执行的一序列命令式语句,而是描 述了希望编译器为我们创建的枚举数类的行为。 u迭代器块中的代码描述了如何枚举元素。 迭代器返回一个泛型枚举数,该枚举数返回三个string类 型的项。 yield return语句声明这是枚举中的下一项。 迭代器块有两个特殊语句: yield return;返回集合的一个元素,并移动到下 一个元素上 。 yield break语句指定在序列中没有更多项。 IListFindBobs(IEnumerable names) var bobs = new List(); foreach(var currName in names) if(currName = “Bob“) bobs.Add(currName); return bobs; IEnumer

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论