更新记录

本文迁移自Panda666原博客,原发布时间:2021年6月30日。

一、迭代器介绍

C#2.0开始,我们可以使用迭代器(iterator)。编译器自动把我们定义的迭代器生成 可枚举类型 或 枚举器。迭代器需要System.Collections.Generic命名空间,要使用using引用它。

using System.Collections.Generic;

二、声明迭代器

迭代器看起来非常像一个方法,但实际上是有本质区别的。编译器将迭代器转换为私有类,然后在类中实现IEnumerable 或者 IEnumerator的方法,即会将其转为可迭代类型。迭代器可以包含在:方法、属性、索引器中。所以迭代器的返回类型只可能是以下四种类型:

System.Collection.IEnumerable
System.Collection.Generic.IEnumerable<T>
System.Collection.IEnumerator
System.Collection.Generic.IEnumerator<T>

在迭代器中通过yield return语句声明枚举中的下一项,枚举器不会一次返回所有元素,每次访问Current属性返回一个新值,iterator可以在method, property, indexer内实现。

实例:返回可枚举类型的迭代器

public class PandaTestClass
{
public IEnumerable<string> GetEnumerator()
{
yield return "Panda";
yield return "Cat";
yield return "Dog";
yield return "Monkey";
yield return "Donkey";
}
}

实例:返回枚举器的迭代器

public class PandaTestClass:IEnumerable<string>
{
public IEnumerator<string> GetEnumerator()
{
yield return "Panda";
yield return "Cat";
yield return "Dog";
yield return "Monkey";
yield return "Donkey";
} IEnumerator IEnumerable.GetEnumerator()
{
throw new NotImplementedException();
}
}

实例:可正序取数也可反向取数的迭代器

public class PandaTestClass
{
private string[] animals { get; set; } public PandaTestClass()
{
this.animals = new string[]
{
"Panda",
"Cat",
"Dog",
"Monkey",
"Donkey"
};
} /// <summary>
/// 正序访问
/// </summary>
/// <returns></returns>
public IEnumerable<string> GetAnimal()
{
foreach (var item in this.animals)
{
yield return item;
}
} /// <summary>
/// 反序访问
/// </summary>
/// <returns></returns>
public IEnumerable<string> GetAnimalReverse()
{
var animalsReversed = this.animals.Reverse();
foreach (var item in animalsReversed)
{
yield return item;
}
}
}

实例:在属性中定义迭代器

class PandaTestClass
{
public IEnumerable<int> SomeProp
{
get
{
yield return 666;
yield return 888;
yield return 999;
}
} public IEnumerator<int> SomeProp2
{
get
{
yield return 666;
yield return 888;
yield return 999;
}
}
}

三、迭代器的内部状态

迭代器在编译器生成的枚举器中,没有实现Reset方法,所以不可以调用Reset。在后台编译器把迭代器转换为的枚举器类包含4个状态:

Before 首次调用MoveNext之前的状态

Running 调用MoveNext后进入这个状态

Supended 状态机等待下次调用MoveNext的状态

After 没有更多项可枚举

四、迭代器与异常处理

yield return语句不可以出现在try/catch/finally语句块中。原因是:迭代器在编译阶段会转为私有类型放在这些语句块中会导致异常复杂。但是可以放在try/finally语句块中。

实例:迭代器的异常处理

IEnumerable<string> Foo()
{
try { yield return "One"; } // OK
finally { ... }
}

最新文章

  1. 修改bootstrap modal模态框的宽度
  2. 打包java项目为可执行程序(exe)
  3. html中input输入框屏蔽鼠标右键
  4. QImage Color Convert to Gray 转为灰度图
  5. HTML5 中已经可以用 Ajax 上传文件了,而且代码非常简单,借助 FormData 类即可发送文件数据。
  6. cdoj 1256 昊昊爱运动 预处理/前缀和
  7. 《HTML5网页开发实例详解》连载(四)HTML5中的FileSystem接口
  8. 【UVA】11732 - strcmp() Anyone?
  9. 用友CDM系统,将货位间商品移库单(一步)修改为内调出入库单(一步)方法使用
  10. nyoj_2:括号配对问题
  11. ES6初体验
  12. L2-023. 图着色问题*
  13. Linux内核分析作业第五周
  14. Java中的List集合和迭代器
  15. 八大排序算法的python实现
  16. Linux——多线程下解决生产消费者模型
  17. 6.824 Lab 5: Caching Extents
  18. 2、Python快速入门(0529)
  19. Oracle连接字符串大全
  20. 2017-2018-2 20155315《网络对抗技术》Exp2:后门原理与实践

热门文章

  1. SpringMVC基于注解开发的步骤
  2. 6.S081-2021-Lab3 Pgtbl学习笔记
  3. IDEA出现Error during artifact deployment. See server log for details.
  4. oracle执行sql查询语句出现错误ORA-00942:表或视图不存在
  5. JDBC 4.0 开始Java操作数据库不用再使用 Class.forName加载驱动类了
  6. Java语言学习day28--8月03日
  7. Handler异步通信系统
  8. windodws pyusb hub端口对应连接的usb设备
  9. c++:-2
  10. Java多线程——实现