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. ASP.NET(支持 ASP.NET MVC)性能优化包 - combres 介绍

    项目地址:https://github.com/buunguyen/combres Overview Combres (previously hosted in CodePlex) helps you ...

  2. [转]Libev教程

    libev Table of Contents 1 libev 1.1 About The Code 1.2 EventLoop 1.3 Watcher 1.4 How it works 1.4.1 ...

  3. sprinfmvc学习--01

    springmvc框架是一个基于请求驱动的web框架,使用了前端控制器模式来设计.根据请求映射规则分发给相应的页面控制器进行处理. 1.  首先用户发送请求-->DispatcherServle ...

  4. SVN版本冲突解决详解

    SVN版本冲突解决详解 分类: SVN(SubVersion)2009-11-23 15:45 27014人阅读 评论(12) 收藏 举报 svnsubversion服务器文档工作c 版本冲突原因: ...

  5. TFS二次开发的数据统计以PBI、Bug、Sprint等为例(一)

    TFS二次开发的数据统计以PBI.Bug.Sprint等为例(一) 在TFS二次开发中,我们可能会根据某一些情况对各个项目的PBI.BUG等工作项进行统计.在本文中将大略讲解如果进行这些数据统计. 一 ...

  6. Silverlight类百度文库在线文档阅读器(转)

    百度文库阅读器是基于Flash的,用Silverlight其实也可以做. 我实现的在线阅读器可以应用于内网文档发布,在线阅览审批等.没有过多的堆积功能,专注于核心功能.主要有以下特性: 1. 基于XP ...

  7. (coco2d-x初学)xcode5.0安装 cocos2d-x2.2.0

    cocos2d-x 2.0版本之后不再支持xcode模板安装. 下面介绍一下创建步骤:我下载的是cocos2d-x2.2.0版本 1.下载Cocos2d-x的地址点击打开链接 2.解压缩压缩包.打开终 ...

  8. 我的API HOOK库

    API HOOK有两种做法,一种是SetWindowHookEx,简单易用,但如果做其它的HOOK,如HOOK OpenProcess,就需要修改内存地址了,内存地址可以通过WriteProcessM ...

  9. 基于Hadoop开发网络云盘系统客户端界面设计初稿

    基于Hadoop开发网络云盘系统客户端界面设计初稿 前言: 本文是<基于Hadoop开发网络云盘系统架构设计方案>的第二篇,针对界面原型原本考虑有两个方案:1.类windows模式,文件夹 ...

  10. Modern 阅读笔记 一 PSR标准

    一.标准 PSR php standards Recommendation PHP 推荐标准 PSR-1 基本代码风格 PSR-2 严格的代码风格  PSR-3 日志记录器接口 PSR-4 自动加载  ...