IEnumerable、IEnumerator接口封装了迭代器功能,有了它,我们不需要将内部集合暴露出去,外界只需要访问我的迭代器接口方法即可遍历数据。

在C#中,使用foreach语句来遍历集合。foreach语句是微软提供的语法糖,使用它可以简化C#内置迭代器的使用复杂性。编译foreach语句,会生成调用GetEnumerator和MoveNext方法以及Current属性的代码。

有两种实现迭代器的方式,一是自己继承IEnumerable接口,比较复杂;二是使用yield,简化操作,下面会有案例。

反编译foreach,生成类似下面这段代码:

 IEnumerator<Student> studentEnumerator = studentList.GetEnumerator();
while (studentEnumerator.MoveNext())
{
var currentStudent = studentEnumerator.Current as Student;
Console.WriteLine("Id = {0}, Name = {1}, Age = {2}", currentStudent.Id, currentStudent.Name, currentStudent.Age);
}

案例1:给自己的类增加迭代器功能

     public class StudentSet : IEnumerable
{
private Student[] students;
public StudentSet(Student[] inputStudents)
{
students = new Student[inputStudents.Length];
for (int i = ; i < inputStudents.Length; i++)
{
students[i] = inputStudents[i];
}
} IEnumerator IEnumerable.GetEnumerator()
{
return (IEnumerator)GetEnumerator();
} public StudentEnumerator GetEnumerator()
{
return new StudentEnumerator(students);
}
} public class StudentEnumerator : IEnumerator
{
public Student[] students;
int position = -;
public StudentEnumerator(Student[] students)
{
this.students = students;
} public bool MoveNext()
{
position++;
return (position < students.Length);
} public void Reset()
{
position = -;
} object IEnumerator.Current
{
get
{
return Current;
}
} public Student Current
{
get
{
try
{
return students[position];
}
catch (IndexOutOfRangeException)
{
throw new InvalidOperationException();
}
}
}
}

案例2:使用yield实现迭代器功能

    public class MyCollection
{
private int[] list = new int[] { , , , }; public IEnumerator<int> GetEnumerator()
{
for (int i = ; i < list.Length; i++)
{
yield return list[i];
}
}
}
 MyCollection col = new MyCollection();
foreach (var item in col)
{
Console.WriteLine(item);
}

IEnumerable、IEnumerator接口(如何增加迭代器功能)的更多相关文章

  1. IEnumerable, IEnumerator接口

    IEnumerable接口 // Exposes the enumerator, which supports a simple iteration over a non-generic collec ...

  2. C# ~ 从 IEnumerable / IEnumerator 到 IEnumerable<T> / IEnumerator<T> 到 yield

    IEnumerable / IEnumerator 首先,IEnumerable / IEnumerator 接口定义如下: public interface IEnumerable /// 可枚举接 ...

  3. 迭代器学习之一:使用IEnumerable和IEnumerator接口

    写博客是检验我学习的成果之一以及自我总结的一种方式,以后会经常利用这种方式进行技术交流和自我总结,其中认识不深难免会有错误,但是一直懂得不懂就问,不懂就学的道理! 1.首先看一个简单的列子 , , , ...

  4. C# 通过IEnumberable接口和IEnumerator接口实现自定义集合类型foreach功能

    1.IEnumerator和IEnumerable的作用 其实IEnumerator和IEnumerable的作用很简单,就是让除数组和集合之外的类型也能支持foreach循环,至于foreach循环 ...

  5. C# 通过IEnumberable接口和IEnumerator接口实现泛型和非泛型自定义集合类型foreach功能

    IEnumerator和IEnumerable的作用 其实IEnumerator和IEnumerable的作用很简单,就是让除数组和集合之外的类型也能支持foreach循环,至于foreach循环,如 ...

  6. 细说 C# 中的 IEnumerable和IEnumerator接口

    我们先思考几个问题: 为什么在foreach中不能修改item的值? 要实现foreach需要满足什么条件? 为什么Linq to Object中要返回IEnumerable? 接下来,先开始我们的正 ...

  7. C#基础知识系列九(对IEnumerable和IEnumerator接口的糊涂认识)

    前言 IEnumerable.IEnumerator到现在为止对这两个接口还是不太理解,不理解但是自己总是想着试着要搞明白,毕竟自己用的少,所以在此先记录一下.以备自己日后可以来翻查,同时也希望园子里 ...

  8. C# IEnumerable 和 IEnumerator接口浅析

    温故而知新,可以为师矣,有空经常复习一下基础知识是有必要的,并且能加深理解和记忆. Foreach常用于循环访问集合,对实现IEnumerable的接口的容器进行遍历,IEnumerable和IEnu ...

  9. IEnumerable和IEnumerator接口

    我们先思考几个问题:1.为什么在foreach中不能修改item的值?(IEnumerator的Current为只读)2.要实现foreach需要满足什么条件?(实现IEnumerator接口来实现的 ...

随机推荐

  1. 【2019-08-29】让自己着眼当下,真TM不容易

    07:50 天是蓝色的,路面是灰色的,树是绿色的,那个奶茶店的招牌是白色的.我的表情是木讷的,老婆的表情是嫌弃的,那个路人的表情是无解的,地铁工作人员的表情是无奈的刚才回到公司看到那个通宵了的同事的表 ...

  2. nodejs的child_process

    child_process  模块提供了衍生子进程的能力 异步方式:spawn.exec.execFile.fork 同步方式:spawnSync.execSync.execFileSync 说明: ...

  3. java内存简单描述

    分为四块:data segment,code segment,堆,栈. data segment :数据段,存放静态变量,字符串常量. code segment:代码段,存放代码. 栈:存放局部变量. ...

  4. VUE方法

    1.$event 变量 $event 变量用于访问原生DOM事件. <!DOCTYPE html> <html lang="zh"> <head> ...

  5. Oppo Reno2 不允许安装非正式签名应用

    一.背景 为了安全起见,开发者本地开发和Jenkins上正式构建时,App采取的签名文件是不一样的.本地开发采取通用的如debug.keystore,正式签名文件部署在服务端.现在不少机型,如Oppo ...

  6. 一个小巧,也很nice的“小日历”--一个Android App

    一个小巧也很Nice的“小日历” 背景 因为,常用日历记一些事情,Android自带的日历,如果有事情,会显示一个小点,然后点击进去后才能看到事情的具体内容,不是很方便. 所以,写了一个“小日历” 特 ...

  7. golang学习笔记 --flag

    概述 flag包提供了一系列解析命令行参数的功能接口 命令行语法 命令行语法主要有以下几种形式 -flag //只支持bool类型 -flag=x -flag x //只支持非bool类型 以上语法对 ...

  8. WPF 精修篇 动态资源

    原文:WPF 精修篇 动态资源 动态资源 使用 DynamicResource 关键字 静态 就是 StaticResource 原则上是 能用静态就用静态 动态会让前台界面压力很大~ 动态资源引用 ...

  9. [转] golang 字符串比较是否相等

    1 前言 strings.EqualFold不区分大小写,"==" 区分且直观. 2 代码 golang字符串比较的三种常见方法 fmt.Println("go" ...

  10. Linux 集群概念 , wsgi , Nginx负载均衡实验 , 部署CRM(Django+uwsgi+nginx), 部署学城项目(vue+uwsgi+nginx)

    Linux 集群概念 , wsgi , Nginx负载均衡实验 , 部署CRM(Django+uwsgi+nginx), 部署学城项目(vue+uwsgi+nginx) 一丶集群和Nginx反向代理 ...