**用yield return 语句实现一个简单结合** - HelloCollection 类包括GetEnumerator()方法。该方法的实现代码包含两条yield return语句,它们分别返回字符串Hello和World ``` using System; using System.Collections; namepace Wrox.ProCSharp.Arrays { public class HelloCollection { public IEnumeratorGetEnumerator() { yield return"HEllo"; yield return "World"; } } } 现在可以用foreach语句迭代集合 public void HelloWord() { var helloCollection=new HelloCollection(); foreach(var s in helloCollection) { WriteLine(s); } } ``` -包含yield 语句的方法或属性也称为迭代块。迭代块必须声明为返回IEnumerator或IEnumerable接口,或者这些接口的泛型版本,这个块可以包含多条yield return语句或yield break 语句,但不能包含return语句。 - 下面例子,可以把yield类型看做内部类Enumerator。外部类的GEtEnumerator()方法实例化并返回一个新的yield类型。在yield类型中,变量state定义了迭代的当前位置,每次调用MoveNext()时,当前位置都会改变。MoveNext()封装了迭代块的代码,并设置了current变量的值,从此使Current属性根据位置返回一个对象。 ``` public class HelloCollection { public IEnumerator GetEnumerator()=>new Enumerator(0); public class Enumerator :IEnumerator,IEnumerator,IDisposable { private int_state; private string _current; public Enumerator(int state) { _state =state; } bool System.Collections.IEnumerator.MoveNext() { switch(state) { case 0: _current="Hello"; _state=1; return true; case 1: _current="World"; _state=2; return true; case 2: break; } return false; } void System.Collections.IEnumerator.Reset() { throw new NotSupportedException(); } string System.Collections.Generic.IEnumerator.Current=>current; void IDisposable.Dispose() {} } } ``` > 用yield return 返回枚举器 - 例子说明:在Tic-Tac-Toe 游戏中有9个域,玩家轮流在这些域中放置一个“十”字或一个圆。这些移动操作由GameMoves类模拟。方法Cross()和Circle()是创建迭代类型的迭代块。在Cross()迭代块中,将移动操作的信息写到控制台上,并递增移动次数。如果移动次数大于8,就用yield break停止迭代;否则,就在每次迭代中返回yield类型circle的枚举对象。Circle()迭代块非常类似于Cross()迭代块,知识它在每次迭代中返回cross迭代器类型 ``` public class GameMoves { private IEnumerator _cross; private IEnumerator _circle; public GameMoves() { _cross=Cross(); _circle=Circle(); } private int _move=0; const int MAxMoves=9; public IEnumerator Cross() { while (true) { WriteLine($"Cross,move {_move}"); if(++_move >=MaxMoves) { yield break; } yield return _circle; } } public IEnumerator Circle() { while(true) { WriteLine($"Circle,move{move}"); if(++_move>=MaxMoves) { yield break; } yield return _cross; } } } ```