迭代器是一种方法、get 访问器或运算符,它通过使用 yield 关键字对数组或集合类执行自定义迭代。yield 返回语句会导致源序列中的元素在访问源序列中的下一个元素之前立即返回给调用方。尽管您以方法的形式编写迭代器,但编译器会将其转换为一个实际上是状态机的嵌套类。只要客户端代码中的 foreach 循环继续进行,此类就会跟踪迭代器的位置。
将使用 foreach 语句从客户端代码中调用迭代器。在为类或结构创建迭代器时,您不必实现整个 IEnumerator 接口。当编译器检测到迭代器时,它将自动生成 IEnumerator 或 IEnumerator<(Of <(T>)>) 接口的 Current、MoveNext 和 Dispose 方法。
迭代器是可以返回相同类型的值的有序序列的一段代码
迭代器可用作方法、运算符或 get 访问器的代码体。
迭代器代码使用 yield return 语句依次返回每个元素。yield break 将终止迭代。
可以在类中实现多个迭代器。每个迭代器都必须像任何类成员一样有唯一的名称,并且可以在 foreach 语句中被客户端代码调用,如下所示:foreach(int x in SampleClass.Iterator2){}。迭代器的返回类型必须为 IEnumerable、IEnumerator、IEnumerable<(Of <(T>)>) 或 IEnumerator<(Of <(T>)>)。迭代器是 LINQ 查询中延迟执行行为的基础。yield 关键字用于指定返回的一个或多个值。到达 yield return 语句时,会保存当前位置。下次调用迭代器时将从此位置重新开始执行。
迭代器对集合类特别有用,它提供一种简单的方法来迭代复杂的数据结构(如二进制树)。
下面举两个自定义集合类中,迭代器的使用,可以大大减少代码的使用量。
using System;using System.Collections;namespace Yield{ class Week : IEnumerable { string[] Days = { "星期1", "星期2", "星期3", "星期4", "星期5", "星期6", "星期7" }; public IEnumerator GetEnumerator() { for (int i = 0; i < Days.Length; ++i) { yield return Days[i]; } } } class Test { static void Main() { Week week = new Week(); foreach (string day in week) { Console.WriteLine(day); } Console.ReadKey(); } }}
重新使用迭代器实现前面的自定义的Library(集合)类
using System.Collections;
using System;
namespace Library { class Library : IEnumerable { ArrayList books;
public Library()
{ books = new ArrayList();
} public void Remove(
string book)
{ books . Remove(
book);
} public void Add(
string book)
{ books . Add(
book);
} public IEnumerator GetEnumerator()
{ // for (int i = 0; i < books.Count; i++) //{ // yield return books[i]; // } foreach (
string book in books)
{ yield return book;
} } } class Test { static void Main()
{ Library lib = new Library();
lib . Add(
"《广告》");
lib . Add(
"《传播学》");
lib . Add(
"《传媒研究》");
lib . Add(
"《市场调研》");
Console . WriteLine(
"说含有的课本包括:");
foreach (
string name in lib)
{ Console . WriteLine(
name);
} Console . ReadKey();
} } }