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. 推荐一款移动端小视频App玲珑视频

    推荐一款移动端小视频App玲珑视频 一 应用描述 玲珑小视频,边看边聊![海量视频,刷个不停,还能找妹子语音聊天哦][随手拍一拍,记录美好生活,还能拿金币哦][看视频领金币.登录领金币.拍视频领金币. ...

  2. LeetCode 167:两数之和 II - 输入有序数组 Two Sum II - Input array is sorted

    公众号: 爱写bug(ID:icodebugs) 给定一个已按照升序排列 的有序数组,找到两个数使得它们相加之和等于目标数. 函数应该返回这两个下标值 index1 和 index2,其中 index ...

  3. addpath(),genpath()

    clear all:clear clc: addpath(): 打开不在同一目录下的文件 addpath('sparse-coding');%sparse-coding,SIFT均表示路径,此目录下的 ...

  4. ng 使用阿里巴巴矢量图

    1.进入阿里巴巴矢量图标库中,选择需要下载的图标,添加进项目中 2.进去项目选择Font class 模式,然后下载到本地 3.解压下载的压缩包,把.css/.svg/.ttf/.woff/.woff ...

  5. 使用thanos管理Prometheus持久化数据

    关于thanos的介绍可以参考这篇官方博客的翻译文档,本文不作部署操作介绍.下图是thanos的官方架构图,主要有5个组件: Query:可以近似看作是Prometheus的实现,用于采集其他组件的数 ...

  6. linux下c++如何输入不回显

    #include <stdio.h> #include <termios.h> #include <unistd.h> #include <iostream& ...

  7. C语言memset()函数:将内存的前n个字节设置为特定的值

    头文件:#include <string.h> memset() 函数用来将指定内存的前n个字节设置为特定的值,其原型为:    void * memset( void * ptr, in ...

  8. Dart面向对象编程(二)

    继承: person.dart: class Person{ String name; int age; String _birthday; bool get isAdult => age &g ...

  9. 【模板整合计划】NB数论

    [模板整合计划]NB数论 一:[质数] 1.[暴力判] 素数.コンテスト.素数 \(\text{[AT807]}\) #include<cstdio> #include<cmath& ...

  10. 前端学习:CSS的学习总结(图解)

    前端学习:CSS的学习总结(图解) CSS代码笔记 CSS简介 css的引入方式和书写规范 CSS选择器 CSS属性 CSS盒子模型 CSS的定位