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的更多相关文章

  1. WebApi XML,Json格式自定义,IEnumerable<T>,ArrayOf

    global.ascx中application-start() GlobalConfiguration.Configuration.Formatters.XmlFormatter.UseXmlSeri ...

  2. 在自己的对象里实现IEnumerator和IEnumerable

    平时工作中我们经常用foreach来迭代一个集合.比如 foreach (Student student in myClass) { Console.WriteLine(student); } 基本所 ...

  3. [No0000B2]ReSharper操作指南3/16-配置ReSharper与代码校错

    配置ReSharper ReSharper功能具有默认配置,这些配置基于.NET世界中的约定和最佳实践.但是,每个功能都可以根据您的需求和喜好灵活调整. ReSharper首选项可以在以下位置进行配置 ...

  4. 21扩展IEnumerable<T>泛型接口自定义LINQ的扩展方法

    LINQ方法实际上是对IEnumerable<TSource>的扩展,如图:   本篇自定义一个MyWhere方法,达到与Where相同的效果.     使用LINQ自带的Where方法 ...

  5. MS SQL自定义函数IsPositiveInteger MS SQL自定义函数IsNumeric 水晶报表使用IEnumerable<T>数据源

    MS SQL自定义函数IsPositiveInteger   判断字符串是否为正整数,0开始的的数字不算. SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON ...

  6. 实现自定义集合的可枚举类型(IEnumerable)和枚举数(IEnumerator )

    下面的代码示例演示如何实现自定义集合的 IEnumerable 和 IEnumerator 接口: using System; using System.Collections; using Syst ...

  7. 自定义一个可以使用foreach语句进行迭代的类(IEnumerable)

    在c#中,凡是实现了IEnumerable接口的数据类型都可以用foreach语句进行迭代访问.所以,我们要定义一个可以使用foreach进行迭代访问的类,就必须要实现IEnumerable接口. / ...

  8. C# 索引器,实现IEnumerable接口的GetEnumerator()方法

    当自定义类需要实现索引时,可以在类中实现索引器. 用Table作为例子,Table由多个Row组成,Row由多个Cell组成, 我们需要实现自定义的table[0],row[0] 索引器定义格式为 [ ...

  9. 实现MVC自定义过滤器,自定义Area过滤器,自定义Controller,Action甚至是ViewData过滤器

    MVC开发中几种以AOP方式实现的Filters是非常好用的,默认情况下,我们通过App_Start中的FilterConfig来实现的过滤器注册是全局的,也就是整个应用程序都会使用的,针对单独的Fi ...

随机推荐

  1. iOS基础 - 控件属性

    一.控件的属性 1.CGRect frame 1> 表示控件的位置和尺寸(以父控件的左上角为坐标原点(0, 0)) 2> 修改这个属性,可以调整控件的位置和尺寸 2.CGPoint cen ...

  2. Aforge.net 一个专门为开发者和研究者基于C#框架设计

    时间过得真快啊,转眼今年就要过去了,大半年都没有写博客了,要说时间嘛,花在泡妹子和搞英语去了,哈哈...前几天老大问我 怎么这么长时间都没写博客了,好吧,继续坚持,继续分享我的心得体会. 这个系列我们 ...

  3. c#实现microsoft账号登入授权(OAuth 2.0)并获取个人信息

    本博主要介绍microsoft 账号授权(OAuth 2.0)登入并获取用户信息的过程,因为写过google账号授权登入的过程,所以这里就简单介绍一下,google授权登入参考地址:http://ww ...

  4. Javascript:看 Javascript 规范,学 this 引用,你会懂的。

    目录 背景this待分析程序先看一个语言规范方法调用备注 背景返回目录 Javascript 的 this 是我的心病,多数情况下知道其运行结果,个别变态的场景下,就给不出解释了,昨天一次偶然的机遇让 ...

  5. SQL Server 如何读写数据

    01. SQL Server 如何读写数据   一. 数据读写流程简要SQL Server作为一个关系型数据库,自然也维持了事务的ACID特性,数据库的读写冲突由事务隔离级别控制.无论有没有显示开启事 ...

  6. 安装Win8

    老毛桃安装Win8(哪里不会点哪里,so easy) 先来一张美女图,是不是很漂亮呢!继续往下看! 求推荐啊! 对于一个干IT的码农来说,会写代码不算什么,会装系统不算什么,及会写代码也会装系统的那才 ...

  7. Jquery EasyUI tabs处理

    一 获取选中的 Tab 1.   // 获取选中的 tab panel 和它的 tab 对象 2.  var pp = $('#tt').tabs('getSelected'); 3.  var ta ...

  8. PyQt设计流程

    Qt designer 设计流程:  创建一个 PyQt4 的步骤,通常的方法是用 QtDesigner 工具创建 GUI 界面.可以在窗口  上添加部件,并可以对部件进行一些属性配置.一般的过程如下 ...

  9. asp.net中的路由系统

    ASP.NET MVC重写了ASP.NET管道HttpModule和处理程序HttpHandler.MVC自定义了MvcHandler实现了Controller的激活和Action的执行.但是在请求到 ...

  10. HDU 3127 WHUgirls dp背包问题

    WHUgirls Time Limit: 3000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total ...