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. Linq无聊练习系列4--join练习

    /**************join 练习*******************/            //对于1对多关系            var list =from c in ctx.T ...

  2. ASP添加进度条

    今日在学习JavaScript所有写个通用的进度条,防止网页假死.让用户更清楚地知道此网页正在进行加载或者处理一些事情,所有加载进度条是一个网站的必要性. 在网页中Page_load首先要加载此进度条 ...

  3. Google Adsense(Google网站联盟)广告申请指南

    Google AdSense 是一种获取收入的快速简便的方法,适合于各种规模的网站发布商.它可以在网站的内容网页上展示相关性较高的 Google 广告,并且这些广告不会过分夸张醒目.由于所展示的广告同 ...

  4. NodeJS的url信息截取模块url-extract

    NodeJS的url信息截取模块url-extract2013-09-12 22:49 by Justany_WhiteSnow, 212 阅读, 0 评论, 收藏, 编辑 上一篇文章,介绍了怎么利用 ...

  5. wxWidgets的安装编译、相关配置、问题分析处理

    wxWidgets的安装编译.相关配置.问题分析处理 一.介绍部分 (win7 下的 GUI 效果图见 本篇文章的最后部分截图2张) wxWidgets是一个开源的跨平台的C++构架库(framewo ...

  6. Ubuntu12.04安装配置Theano

    上次写了一个关于DL的开篇内容,本来说是要继续跟进的,后来教研室里面出了一些事情,加上写论文.和隔壁教研室做实验,就一直拖到现在.早就让小K配置环境研究研究Theano,这货和我一样也发拖延症了,理由 ...

  7. 【最新】让快捷方式 实现相对路径——非.bat方式实现

    快捷方式一般是使用绝对路径的,但并不是不能使用相对路径,系统为普通用户考虑一般默认使用绝对路径,这样的结果是:只要目标文件(不论是文件夹.程序.文档,也包括快捷方式)绝对位置不变,我们创建的快捷方式基 ...

  8. 对Conjugate Gradient 优化的简单理解

    对Conjugate Gradient 优化的简单理解) 机器学习&数据挖掘笔记_12(对Conjugate Gradient 优化的简单理解) 数学优化方法在机器学习算法中至关重要,本篇博客 ...

  9. iOS 开发问题集锦(一)

    最近在QQ群里好多人问一些比较基础的问题,在这罗列一下: 1.键盘上的斜杠键坏掉了,怎么样用快捷键进行注释呢? 首先在Xcode中注释的默认快捷键为:command+/: 其次可以自行修改快捷键:Xc ...

  10. 横瓜从WP7与WP8不兼容之处预测微软公司在未来20年将会倒闭

    横瓜(601069289)  12:40:50 微软频繁升级操作系统版本捞钱,还不向下兼容,其企业的核心竞争力不再是技术,是钱!除了操作系统,其它产品没有任何核心技术和竞争力,微软必死. 横瓜从WP7 ...