-
C# 1.0手写迭代器的痛苦
public class IterationSample : IEnumerable
{
object[] values;
int startingPoint;
public IterationSample(object[] values, int startingPoint)
{
this.values = values;
this.startingPoint = startingPoint;
}
public IEnumerator GetEnumerator()
{
return new IterationSampleIterator(this);
}
class IterationSampleIterator : IEnumerator
{
IterationSample parent; //正在迭代的集合
int position;//指出遍历到的位置
internal IterationSampleIterator(IterationSample parent)
{
this.parent = parent;
position = -1;//在第一个元素之前开始
}
public object Current
{
get
{
if (position == -1 || position == parent.values.Length)
{
throw new InvalidOperationException();
}
int index = position + parent.startingPoint;
index = index % parent.values.Length;
return parent.values[index];
}
}
public bool MoveNext()
{
if (position != parent.values.Length)//如果仍要遍历,增加position的值
{
position++;
}
return position < parent.values.Length;
}
public void Reset()
{
position = -1;
}
}
}
class Program
{
static void Main(string[] args)
{
object[] values = { "a", "n", "c", "d", "e" };
IterationSample collection = new IterationSample(values, 3);
foreach (var x in collection)
{
Console.WriteLine(x);
}
}
}
-
C# 2.0利用yield语句简化迭代器
public IEnumerator GetEnumerator()
{
//return new IterationSampleIterator(this);
for (int index = 0; index < values.Length; index++)
{
yield return values[(index + startingPoint) % values.Length];
}
}
- yield return 告诉编译器这不是一个普通的方法,而是实现一个迭代器块的方法。这个方法被声明为返回一个IEnumerator接口。
- 实际上是请求编译器为你创建了一个状态机,编译器这样做的原因是调用者每次只想获取一个元素,所以在返回上一个值时需要跟踪当前的工作状态。
- yield return语句只表示“暂时地”退出方法,事实上你可以把它当作暂停。