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. C# HTTP系列8 GET与POST对比说明

    系列目录     [已更新最新开发文章,点击查看详细]  HTTP协议,即超文本传输协议(Hypertext transfer protocol).是一种详细规定了浏览器和万维网(WWW = Worl ...

  2. SpringBoot集成Spring Security(4)——自定义表单登录

    通过前面三篇文章,你应该大致了解了 Spring Security 的流程.你应该发现了,真正的 login 请求是由 Spring Security 帮我们处理的,那么我们如何实现自定义表单登录呢, ...

  3. Task和async/await详解

    一.什么是异步 同步和异步主要用于修饰方法.当一个方法被调用时,调用者需要等待该方法执行完毕并返回才能继续执行,我们称这个方法是同步方法:当一个方法被调用时立即返回,并获取一个线程执行该方法内部的业务 ...

  4. POI 操作 excel表格 (简单整理)

    简单的整理: import org.apache.poi.ss.usermodel.*; import org.apache.poi.ss.util.CellRangeAddress; import ...

  5. HTML连载30-CSS显示模式&模式转换

    一.CSS显示模式​ 1.在HTML中HTML将所有的标签分为两类,分别是容器类和文本级.在CSS中CSS也将所有的标签分为两类,分别是块级元素和行内元素 2.什么是块级元素呢?什么是行内元素​? ( ...

  6. PCA:主成分分析

    PCA的概念: 主要思想是将n维特征映射到k维上,这k维是全新的正交特征,这k维特征被称为主成分,在原数据的基础上重新构造出来k维.就是从原始的空间顺序的找出一组相互正交的坐标轴,新坐标轴的选择和数据 ...

  7. C++:inline

    inline inline是C++提供的一个关键字,它用于函数定义之前,表示把函数定义为内联函数.内联函数的含义是:在函数调用点把函数体直接展开,取代函数调用. inline int getZero( ...

  8. Kubernetes管理GPU应用

    目录 简介 GPU驱动 Nvidia-docker Nvidia-device-plugin 在Kubernetes上运行GPU应用 附录 简介 伴随着人工智能技术的发展,机器学习的应用场景越来越广泛 ...

  9. spring-session-jdbc 使用

    这个文档比较有用了,参考: https://www.cnblogs.com/davidwang456/p/10361550.html>https://www.cnblogs.com/davidw ...

  10. 2019-11-29-win10-uwp-如何判断一个控件在滚动条的里面是用户可见

    原文:2019-11-29-win10-uwp-如何判断一个控件在滚动条的里面是用户可见 title author date CreateTime categories win10 uwp 如何判断一 ...