C#基础——迭代器
迭代器是一种方法、get访问器或运算符,它通过使用yield关键字对数组或集合类执行自定义迭代。yield返回语句会导致源序列中的元素在访问源序列中的下一个元素之前立即返回给调用方。尽管以方法的形式编写迭代器,但编译器会将其转换为一个实际上时状态机的嵌套类。只要客户端代码中的foreach循环继续进行,此类就会跟踪迭代器的位置。
1、迭代器是可以返回相同类型的值的有序序列的一段代码
2、迭代器可用作方法、运算符或get访问器的代码体
3、迭代器代码使用yield return语句依次返回每个元素。yield break将终止迭代
4、可以再类中实现多个迭代器
5、迭代器的返回类型必须为IEnumerable,IEnumerator,IEnumerable<T>或IEnumerator<T>
6、迭代器是LINQ查询中延迟执行行为的基础
示例1、简单示例:foreach循环每迭代一次,都返回集合中的下一个字符串。
-
using System; using System.Collections.Generic; using System.Collections;
-
public class DaysOfTheWeek:IEnumerable { string[] m_Days = { "Sun", "Mon", "Tue", "Wed", "Thr", "Fri", "Sat" }; public IEnumerator GetEnumerator() { for(int i=0;i<m_Days.Length;i++) { yield return m_Days[i]; } } } public class Program { public static void Main() { DaysOfTheWeek week=new DaysOfTheWeek(); foreach(string day in week) { Console.Write(day+" "); } Console.WriteLine(); Console.WriteLine("Press Enter to close this window."); Console.ReadLine(); } }
输出:
示例2、为整数列表创建迭代器块
-
using System; using System.Collections.Generic; using System.Collections;
-
public class SampleCollection { public int [] items; public SampleCollection() { items=new int[5]{5,4,7,3,9}; } public IEnumerable BulidCollection() { for(int i=0;i<items.Length;i++) { yield return items[i]; } } } public class Program { public static void Main() { SampleCollection col=new SampleCollection(); Console.WriteLine("Vaules in the collection are:"); foreach(int i in col.BulidCollection()) { Console.Write(i+" "); } Console.WriteLine(); Console.WriteLine("Press Enter to close this window."); Console.ReadLine(); } }
输出:
示例3、为泛型列表创建迭代器块
-
using System; using System.Collections; using System.Collections.Generic;
-
namespace GenericIteratorExample { public class Stack<T> : IEnumerable<T> { private T[] values=new T[100]; private int top=0; public void Push(T t) { values[top++]=t; } public T Pop() { return values[--top]; } public IEnumerator<T> GetEnumerator() { for(int i=top-1;i>=0;i--) { yield return values[i]; } } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } public IEnumerable<T> TopToBottom { get { return this; } } public IEnumerable<T> BottomToTop { get { for(int i=0;i<top;i++) { yield return values[i]; } } } public IEnumerable<T> TopN(int n) { int j=n>=top?0:top-n; for(int i=top;--i>=j;) { yield return values[i]; } } } public class Program { public static void Main() { Stack<int> s=new Stack<int>(); for(int i=0;i<10;i++) { s.Push(i); } foreach(int n in s) { Console.Write("{0} ",n); } Console.WriteLine(); foreach(int n in s.TopToBottom) { Console.Write("{0} ",n); } Console.WriteLine(); foreach(int n in s.BottomToTop) { Console.Write("{0} ",n); } Console.WriteLine(); foreach(int n in s.TopN(5)) { Console.Write("{0} ",n); } Console.WriteLine(); Console.WriteLine(); Console.WriteLine("Press Enter to close this window."); Console.ReadLine(); } } }
输出: