11.C#迭代器(六章6.1)

  今天我们说下C#中的迭代器,首先引出一些关于迭代的概念,后面举出代码供大家讨论。

  迭代器模式是行为模式的一种范例,行为模式是一种简化对象之间通信的一种设计模式。在.NET中使用IEnumerator和IEnumerable接口及它们的泛型等价物来封装的,如果一个类型实现了IEnumerable接口,就说明它是可迭代的,调用GetEnumerator方法返回IEnumerator的实现,这是迭代器本身。

  C#1使用foreach语句实现了访问迭代器的内置支持,foreach语句会被编译成使用GetEnumerator和MoveNext方法以及Current属性。C#中迭代器只能向后访问,而C++中迭代器可以支持前后访问。

  背景,假设有一个关于学生的队列,每个学生依次报出自己的名字,Student类如下

 1 class Student
 2 {
 3     public string Name { get; set; }
 4
 5     public Student(string name)
 6     {
 7         Name = name;
 8     }
 9
10     public void SayName()
11     {
12         Console.WriteLine(Name);
13     }
14 }

  有一个实现IEnumerable的Queue的泛型类,如下

 1 class Queue<T> : IEnumerable<T> where T : class
 2 {
 3     public List<T> objects = new List<T>();
 4
 5     public Queue(List<T> list)
 6     {
 7         objects = list;
 8     }
 9
10     //实现从IEnumerable中的GetEnumerator方法
11     /*
12         个人觉得这个方法在迭代中只会调用一次,不然每次都返回一个新的QueueIterator<T>对象,位置记录都会重置为-1
13     */
14     public IEnumerator<T> GetEnumerator()
15     {
16         return new QueueIterator<T>(this);
17     }
18
19     IEnumerator IEnumerable.GetEnumerator()
20     {
21         throw new NotImplementedException();
22     }
23 }

  使用GetEnumerator方法返回一个迭代器,而迭代器需要实现IEnumerator接口,如下

 1 class QueueIterator<T> : IEnumerator<T> where T : class
 2 {
 3     private ConsoleDemo.Chapter6.Queue<T> q = null;
 4
 5     int startPoint = -1;    //用于保存游标的位置
 6
 7     public QueueIterator(ConsoleDemo.Chapter6.Queue<T> q)
 8     {
 9         this.q = q;
10     }
11
12     //返回合适位置上的T类型实例,这个例子中调用提这个自动属性
13     public T Current
14     {
15         get
16         {
17             if (startPoint==-1 || startPoint==q.objects.Count)
18             {
19                 throw new InvalidOperationException();
20             }
21             int index = startPoint + q.objects.Count;
22             index = index % q.objects.Count;
23             return q.objects[index];
24         }
25     }
26
27     object IEnumerator.Current
28     {
29         get
30         {
31             if (startPoint == -1 || startPoint == q.objects.Count)
32             {
33                 throw new InvalidOperationException();
34             }
35             int index = startPoint + q.objects.Count;
36             index = index % q.objects.Count;
37             return q.objects[index];
38         }
39     }
40
41     public void Dispose()
42     {
43
44     }
45
46     public bool MoveNext()
47     {
48         if (startPoint != q.objects.Count)
49         {
50             startPoint++;
51         }
52         return startPoint < q.objects.Count;
53     }
54     //当迭代结束后,会调用这个方法,则下一次迭代后重新从第一个位置开始
55     public void Reset()
56     {
57         startPoint = -1;
58     }
59 }

  分别要去实现从IEnumerator中的Current属性、Dispose方法(有必要的话)、MoveNext方法、Reset方法。使用C#2中的yield语句可以简化迭代器,再下一篇中再说。

  请斧正。

  

时间: 2024-10-03 04:33:42

11.C#迭代器(六章6.1)的相关文章

ASP.NET MVC with Entity Framework and CSS一书翻译系列文章之第六章:管理产品图片:多对多关系(上)

这章介绍了怎样创建一个新的实体来管理图片,怎样使用HTML窗体来上传图片文件和使用多对多关系来使它们与产品相关,并且怎样来保存图片到文件系统中.这章也介绍了更多复杂的错误处理增加客户端错误到模型中为了把它们显示回给用户.在这章中播种数据库使用的产品图片可能在在第六章的从Apress网页站点下载代码中. 注意:如果你想遵从这章的代码,你必须完成第五章的代码或者从www.apress.com下载第五章的源代码作为一个起点. 创建实体保存图片文件名 这个项目,我们正要使用文件系统在Web项目中存储图片

CSS3秘笈:第六章

第六章  文本格式化 1.font-family 属性设置字体.除了指定想要的字体之外还要使用备用字体.例如: p{ font-family:Arial ,Helvetica ,sans-serif; } 如果字体的名称中包含多个单词,则必须用双引号(””)将它们括起来. 2.·serif字体,适合冗长的文字信息. ·sans-serif字体看起来干净而整洁因此经常被放在标题上. ·monospaced字体经常用于显示计算机代码.字体中的每个字母都是等宽的. ·其他常用字体:Arial Blac

《Entity Framework 6 Recipes》中文翻译系列 (30) ------ 第六章 继承与建模高级应用之多对多关联

翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 第六章  继承与建模高级应用 现在,你应该对实体框架中基本的建模有了一定的了解,本章将帮助你解决许多常见的.复杂的建模问题,并解决你可能在现实中遇到的建模问题. 本章以多对多关系开始,这个类型的关系,无论是在现存系统还是新项目的建模中都非常普遍.接下来,我们会了解自引用关系,并探索获取嵌套对象图的各种策略.最后,本章以继承的高级建模和实体条件结束. 6-1  获取多对多关联中的链接表 问题

Python核心编程(第二版) 第六章习题答案

6–1.字符串.string 模块中是否有一种字符串方法或者函数可以帮我鉴定一下一个字符串是否是另一个大字符串的一部分? 答:有,string.find(str,beg,end) 6–2.字符串标识符.修改例 6-1 的 idcheck.py 脚本,使之可以检测长度为一的标识符,并且可以识别 Python 关键字,对后一个要求,你可以使用 keyword 模块(特别是 keyword.kelist)来帮你. 1 #!/usr/bin/python 2 3 import string 4 impo

OpenGL ES着色器语言之语句和结构体(官方文档第六章)内建变量(官方文档第七、八章)

OpenGL ES着色器语言之语句和结构体(官方文档第六章) OpenGL ES着色器语言的程序块基本构成如下: 语句和声明 函数定义 选择(if-else) 迭代(for, while, do-while) 跳跃(discard, return, break, continue) 6.1函数定义   着色器是由一系列全局声明和函数定义组成的.函数声明规范如下: // prototype returnType functionName (type0 arg0, type1 arg1, ...,

JavaScript DOM编程艺术-学习笔记(第五章、第六章)

第五章: 1.题外话:首先大声疾呼,"js无罪",有罪的是滥用js的那些人.js的father 布兰登-艾克,当初为了应付工作,10天就赶出了这个js,事后还说人家js是c语言和self语言"约"的产物,(百度百科说的,这些).....一个可怜的孩子-js.然后命运弄"人",js此时已世人皆知.可能是因为js的毁誉参半,它老爸才不想承认它吧.如果js会说话,它可能会给它布兰登-艾克说,"你当初怎么不把*******在墙上".这

4.11日第11次作业,21章法律法规与标准,22章职业道德规范

4.11日第11次作业,21章法律法规与标准,22章职业道德规范 21章:法律法规和标准规范 22章:职业道德规范 1.中国标准划分为哪四个层次?要求最低的是哪个?P498 答:<中华人民共和国标准化法>将标准划分为4个层次:即国家标准.行业标准.地方标准和企业标准.其中国标最低,企业标准最高. 2.国家标准的制订程序包括哪些?P499中间 答:国家标准的制定有一套正常程序,每一个过程都要按部就班地完成,这个过程分为前期准备.立项.起草.征求意见.审查.批准.出版.复审和废止9个阶段. 3.I

第六章整体管理、第七章范围管理--中项作业

第六章项目整体管理 1.项目整体管理的过程包括如下内容(熟练背): (1)项目启动.制定项目章程,正式授权项目或颈剐阶段的开始. (2)制定初步的项目范围说明书.编制一个初步的项目范围说明书,概要地描述项目的范围. (3)制定项目管理计划.将确定.编写.集成以及拂调所有分计划,以形成整体项目管理计划. (4)指导和管理项目的执行.执行在项强管理计划中所定义的工作以达到项目的目标. (5)监督和控制项目.监督和控制项目的启动.计划.执行和收尾过程,以达到项目管理计划所定义的项目目标. (6)整体变

《数据结构与算法分析:C语言描述》复习——第六章“排序”——冒泡排序

2014.06.17 01:04 简介: 冒泡排序是O(n^2)级别的交换排序算法,原理简单,属于必知必会的基础算法之一. 思路: 排序要进行N轮,每一轮从尾部逐个向前扫描,遇到逆序对就进行交换.确保每一轮把最小的元素交换到前面去.这个过程好比水中的气泡向上飘,所以叫冒泡排序.代码非常简单,所以语言描述反而显得麻烦了. 实现: 1 // My implementation for bubble sort. 2 #include <iostream> 3 #include <vector&