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

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

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

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

 class Student
{
public string Name { get; set; } public Student(string name)
{
Name = name;
} public void SayName()
{
Console.WriteLine(Name);
}
}

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

 class Queue<T> : IEnumerable<T> where T : class
{
public List<T> objects = new List<T>(); public Queue(List<T> list)
{
objects = list;
} //实现从IEnumerable中的GetEnumerator方法
/*
个人觉得这个方法在迭代中只会调用一次,不然每次都返回一个新的QueueIterator<T>对象,位置记录都会重置为-1
*/
public IEnumerator<T> GetEnumerator()
{
return new QueueIterator<T>(this);
} IEnumerator IEnumerable.GetEnumerator()
{
throw new NotImplementedException();
}
}

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

 class QueueIterator<T> : IEnumerator<T> where T : class
{
private ConsoleDemo.Chapter6.Queue<T> q = null; int startPoint = -; //用于保存游标的位置 public QueueIterator(ConsoleDemo.Chapter6.Queue<T> q)
{
this.q = q;
} //返回合适位置上的T类型实例,这个例子中调用提这个自动属性
public T Current
{
get
{
if (startPoint==- || startPoint==q.objects.Count)
{
throw new InvalidOperationException();
}
int index = startPoint + q.objects.Count;
index = index % q.objects.Count;
return q.objects[index];
}
} object IEnumerator.Current
{
get
{
if (startPoint == - || startPoint == q.objects.Count)
{
throw new InvalidOperationException();
}
int index = startPoint + q.objects.Count;
index = index % q.objects.Count;
return q.objects[index];
}
} public void Dispose()
{ } public bool MoveNext()
{
if (startPoint != q.objects.Count)
{
startPoint++;
}
return startPoint < q.objects.Count;
}
//当迭代结束后,会调用这个方法,则下一次迭代后重新从第一个位置开始
public void Reset()
{
startPoint = -;
}
}

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

  请斧正。

  

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

  1. 2017.11.2 JavaWeb----第六章 Servlet技术

    JavaWeb ------第六章 Servlet技术 (1)在Web应用程序开发中,一般由JSP JavaBean技术和 Servlet技术的结合实现MVC开发模式.在MVC开发模式中将Web程序的 ...

  2. C#高级编程第11版 - 第六章 索引

    [1]6.2 运算符 1.&符在C#里是逻辑与运算.管道符号|在C#里则是逻辑或运算.%运算符用来返回除法运算的余数,因此当x=7时,x%5的值将是2. [2]6.2.1 运算符的简写 1.下 ...

  3. 简学Python第六章__class面向对象编程与异常处理

    Python第六章__class面向对象编程与异常处理 欢迎加入Linux_Python学习群  群号:478616847 目录: 面向对象的程序设计 类和对象 封装 继承与派生 多态与多态性 特性p ...

  4. 精读《C++ primer》学习笔记(第四至六章)

    第四章: 重要知识点: 4.1 基础 函数调用是一种特殊的运算符,它对运算对象的数量没有限制. 重载运算符时可以定义运算对象的类型,返回值类型,但运算对象的个数,运算符的优先级,结合律无法改变. 当一 ...

  5. 《Entity Framework 6 Recipes》中文翻译系列 (37) ------ 第六章 继承与建模高级应用之独立关联与外键关联

    翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 6-13  在基类中应用条件 问题 你想从一个已存在的模型中的实体派生一个新的实体, ...

  6. Java语言程序设计(基础篇) 第六章 方法

    第六章 方法 6.2 定义方法 1.方法的定义由方法名称.参数.返回值类型以及方法体组成. 2.定义在方法头中的变量称为形式参数(formal parameter)或者简称为形参(parameter) ...

  7. 《Python核心编程》 第六章 序列 - 课后习题

    课后习题 6–1.字符串.string 模块中是否有一种字符串方法或者函数可以帮我鉴定一下一个字符串是否是另一个大字符串的一部分? 答:成员关系操作符(in.not in) import string ...

  8. 第六章SignalR的服务器广播

    第六章SignalR的服务器广播 1.概述: VS可以通过 Microsoft.AspNet.SignalR.Sample NuGet包来安装一个简单的模拟股票行情应用.在本教程的第一部分,您将从头开 ...

  9. perl5 第六章 模式匹配

    第六章 模式匹配 by flamephoenix 一.简介二.匹配操作符三.模式中的特殊字符  1.字符+  2.字符 []和[^]  3.字符 *和?  4.转义字符  5.匹配任意字母或数字  6 ...

随机推荐

  1. 03_汇编语言(n个数找最大值)

    程序要求: 先输入一个数n(0<n<=100),再输入n个无符号数K(0<=K<=65535),找出这n个数的最大值并输出 测试实例保证输入每个数之后,都会以回车结束 代码: ...

  2. Linux gcc命令

    一.简介 GCC 的意思也只是 GNU C Compiler 而已.经过了这么多年的发展,GCC 已经不仅仅能支持 C 语言:它现在还支持 Ada 语言.C++ 语言.Java 语言.Objectiv ...

  3. js清除缓存方法

    1.加入如下头描述 <META HTTP-EQUIV="Pragma" CONTENT="no-cache"> <META HTTP-EQUI ...

  4. B+树的特点

    1.B+树是应文件系统产生的B树的变种.它依然是一颗多路查找树,与B树相比它的不同体现在: (1).如果非叶子节点包含n个关键码,则这个节点有n个子树. (2).非叶子节点仅包含关键码信息,叶子节点包 ...

  5. Windows事件ID大全

    51 Windows 无法找到网络路径.请确认网络路径正确并且目标计算机不忙或已关闭.如果 Windows 仍然无法找到网络路径,请与网络管理员联系. 52 由于网络上有重名,没有连接.请到“控制面板 ...

  6. UESTC 915 方老师的分身II --最短路变形

    即求从起点到终点至少走K条路的最短路径. 用两个变量来维护一个点的dis,u和e,u为当前点的编号,e为已经走过多少条边,w[u][e]表示到当前点,走过e条边的最短路径长度,因为是至少K条边,所以大 ...

  7. HDU 2298 Toxophily 【二分+三分】

    一个人站在(0,0)处射箭,箭的速度为v,问是否能够射到(x,y)处,并求最小角度. 首先需要判断在满足X=x的情况下最大高度hmax是否能够达到y,根据物理公式可得 h=vy*t-0.5*g*t*t ...

  8. DoTween(HOTween V2) 教程

    DoTween资料 官方网站:http://dotween.demigiant.com/ 下载地址:http://dotween.demigiant.com/download.php 快速开始:htt ...

  9. nginx反向代理+缓存开启+url重写+负载均衡(带健康探测)的部署记录

    在日常运维工作中,运维人员会时常使用到nginx的反向代理,负载均衡以及缓存等功能来优化web服务性能. 废话不多说,下面对测试环境下的nginx反向代理+缓存开启+url重写+负载均衡(带健康探测) ...

  10. 用Swift GestureRecognizer 的几个注意点

    最近做了一些关于 GestureRecognizer 的工作 ,随笔记录一些需要注意的点: 1. PanGestureRecognizer (1)在使用时 注意在哪个view添加了 手势识别 self ...