自定义实现IEnumerable
Demo: http://files.cnblogs.com/files/georgeHeaven/Demo.IEnumerable.rar
一、使用场景
在开发过程中,经常需要使用foreach来循环遍历集合中的元素。虽然.net 类库中已经实现了很多的集合类可以足够我们使用,如List<T>,Array<T>等,但是有的时候我们需要自定义一个自己的集合类如:MyList<T> 也能支持foreach的循环遍历。为了能够实现元素的遍历就必须要实现IEnumerable,对于实现该类接口的类对象来说,不但可以支持foreach的循环遍历,还可以使用C#3.0中的一些扩展方法来访问集合元素。
二、实现
场景:我们有两个类,一个是ClassRoom,一个是student类。我们将要自定义一个集合类StudentCollection,该类实现IEnumerable接口。 我们想要使用foreach来遍历StudentCollection中的每一个学生。
而且我们想要我们的客户端代码调用如下:

1. 实现student类:student类将会作为我们遍历的集合元素。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace Demo.IEnumerableInter
{
public class Student
{
public string Name { get; set; } public int Age { get; set; } public string School { get; set; }
}
}
2. 实现ClassRoom类:Classroom类将包含我们自定义的集合,并且通过属性公开给外部访问集合元素。
如下代码中的StudentCollection是我们自定义的集合类(该demo中我们没有涉及泛型的,如果扩展一下我们可以自定义一个泛型集合类如MyCollection<student> students),通过属性Students公开给外部调用。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace Demo.IEnumerableInter
{
public class ClassRoom
{ private StudentCollection studentList; public StudentCollection Students
{
get
{
return studentList;
}
} public ClassRoom()
{
Student[] stus = new Student[]
{
new Student(){Name ="George Li", Age=, School="Shenzhen Universty"},
new Student(){Name ="Ruby zhang", Age=, School="BEIJING Universty"},
new Student(){Name ="Csharp Li", Age=, School="QINGHUA Universty"}
}; studentList = new StudentCollection(stus);
}
}
}
3. IEnumerable 接口实现
首先查看IEnumerable接口如下,为了实现它我们需要实现GetEnumerator()方法。然而该方法返回的却是另一个接口类型IEnumerator(有点叫迭代器),其实不难理解,比如我们自定义类型要实现遍历的接口,你总得告诉你的类你想如何遍历,其实也就是定义一个遍历规则。比如我可以从0开始正序遍历我也可以倒叙遍历,取决于你定义的IEnumerator。

于是我们要先实现一个自己的IEnumerator,查看IEnumerator接口,我们需要实现如下的成员:

现在我们按照接口定义,我们定义一个StudentEnumerator依次实现它的成员:

在实现迭代器以后我们便可以在我们自定义的集合类中实现IEnumerable接口

4. 客户端代码调用
在我们实现了自定义的集合类以后,我们可以在客户端(演示中是控制台输出)通过如下的代码来实现元素的遍历:直接通过我们的自定义集合类,或者通过GetEnumerator使用while来访问(这已经类似于foreach的实现了)
ClassRoom cm1 = new ClassRoom();
//Iterating all students in this class room
Console.WriteLine("-----Iterating with Foreach-----");
foreach (Student stu in cm1.Students)
{
Console.WriteLine("Welcom: ---"+stu.Name);
}
Console.WriteLine("-----Iterating with GetEnumerator------");
System.Collections.IEnumerator stus = cm1.Students.GetEnumerator();
while (stus.MoveNext())
{
Student current = stus.Current as Student;
Console.WriteLine("Welcom: ---" + current.Name);
}
Console.ReadLine();
5. 客户端输出:

【总结】:对于自定义实现IEnumerable接口,最主要在于通过实现IEnumerator接口来设置遍历规则。我们也可以修改上面的例子,通过添加不同的IEnumerator的接口实现,来实现同样的foreach输出不同的结果。这里给了开发人员很大的灵活性。
自定义实现IEnumerable的更多相关文章
- WebApi XML,Json格式自定义,IEnumerable<T>,ArrayOf
global.ascx中application-start() GlobalConfiguration.Configuration.Formatters.XmlFormatter.UseXmlSeri ...
- 在自己的对象里实现IEnumerator和IEnumerable
平时工作中我们经常用foreach来迭代一个集合.比如 foreach (Student student in myClass) { Console.WriteLine(student); } 基本所 ...
- [No0000B2]ReSharper操作指南3/16-配置ReSharper与代码校错
配置ReSharper ReSharper功能具有默认配置,这些配置基于.NET世界中的约定和最佳实践.但是,每个功能都可以根据您的需求和喜好灵活调整. ReSharper首选项可以在以下位置进行配置 ...
- 21扩展IEnumerable<T>泛型接口自定义LINQ的扩展方法
LINQ方法实际上是对IEnumerable<TSource>的扩展,如图: 本篇自定义一个MyWhere方法,达到与Where相同的效果. 使用LINQ自带的Where方法 ...
- MS SQL自定义函数IsPositiveInteger MS SQL自定义函数IsNumeric 水晶报表使用IEnumerable<T>数据源
MS SQL自定义函数IsPositiveInteger 判断字符串是否为正整数,0开始的的数字不算. SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON ...
- 实现自定义集合的可枚举类型(IEnumerable)和枚举数(IEnumerator )
下面的代码示例演示如何实现自定义集合的 IEnumerable 和 IEnumerator 接口: using System; using System.Collections; using Syst ...
- 自定义一个可以使用foreach语句进行迭代的类(IEnumerable)
在c#中,凡是实现了IEnumerable接口的数据类型都可以用foreach语句进行迭代访问.所以,我们要定义一个可以使用foreach进行迭代访问的类,就必须要实现IEnumerable接口. / ...
- C# 索引器,实现IEnumerable接口的GetEnumerator()方法
当自定义类需要实现索引时,可以在类中实现索引器. 用Table作为例子,Table由多个Row组成,Row由多个Cell组成, 我们需要实现自定义的table[0],row[0] 索引器定义格式为 [ ...
- 实现MVC自定义过滤器,自定义Area过滤器,自定义Controller,Action甚至是ViewData过滤器
MVC开发中几种以AOP方式实现的Filters是非常好用的,默认情况下,我们通过App_Start中的FilterConfig来实现的过滤器注册是全局的,也就是整个应用程序都会使用的,针对单独的Fi ...
随机推荐
- c/c++操作访问数据,是堆中的数据快还是栈中的数据快
这里的问题其实问的是对堆与栈的数据访问有什么不同. 观察如下代码: #include<stdio.h> #include<iostream> using namespace s ...
- SublimeText编辑器替代notepad++了
可以考虑使用SublimeText编辑器替代notepad++了 内容目录: 插件安装配置 配置打包下载 大概是去年吧,这款编辑器神一般的出现在我面前,经过我小心翼翼的试用后发现并不是那么太顺手, ...
- 图解Javascript之Function
好东西分享给大家,但要尊重事实!!!因此特别说明:本图非我本人亲自所作,乃我大天朝网友所绘制.个人感觉此图,覆盖全面,细节考虑甚周全,因此分享给大家,同时在此特别感谢网友的无私分享!
- JDBC公共操作类
import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sq ...
- EasyUI tree扩展获取实心节点
<script type="text/javascript"> //扩展 获得tree 的实心节点 $(function(){ $.extend($.fn.tree.m ...
- SpringMVC入门笔记一
SpringMVC优势 性能比struts2好 简单 便捷 易学 和Spring无缝集成(使用spring ioc aop) 约定优于配置 能够简单进行Junit测试 ...
- Ajax实现天气预报功能
实现天气预报功能 闲来无聊,写下此文 经常看见很多网站上有那种天气预报功能,自己之前也写过一个,不过属于那种涉及WCF服务引用那种,今天发现一个更为简单的方式来实现,使用Javascript和Ajax ...
- HDU--杭电--3415--Max Sum of Max-K-sub-sequence--队列--双向队列
Max Sum of Max-K-sub-sequence Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K ...
- 让C#、VB.NET实现复杂的二进制操作
VB.NET和C#属于高级语言,对二进制位操作的支持不是很好,比如没有了移位运算等,用的时候确实很不方便,所以在闲暇之余我重新封装了一个用于C#.VB.NET的位操作类库,通过该类库可以实现数据移位. ...
- 结构-行为-样式-angularJs ngAnimate(Js实现)
声明 页面 Js 注意事项 官方链接 一.声明 注意animate的版本要与Angular的一致. <script src="jquery.1.9.1.min.js"> ...