C# 1.0中的foreach
没有迭代器的时候,创建一个可用于foreach的集合(C# 1.0):
public class MyCollection : IEnumerable
{
public MyEnumerator GetEnumerator()
{
return new MyEnumerator(this);
}
public class MyEnumerator : IEnumerator
{
public void Reset(){...}
public bool MoveNext(){...}
public int Current{ get{...} }
object IEnumerator.Current{ get{...} }
}
}
对集合使用foreach语句:
foreach(int i in col){...}
相单于:
IEnumerator etor = ((IEnumerable)col).GetEnumerator();
try
{
while(etor.MoveNext())
{
ElementType clem (ElementType)etor.Current;
...;
}
}
finally{(IDisposable)enumerator).Dispose();}
C# 2.0 中的迭代器
使用迭代器创建于foreach的集合(C# 2.0):
public class Stack<T>:IEnumerable<T>
{
T[] items;
int count;
public void Push(T data){...}
public T Pop(){...}
public IEnumerator<T> GetEnumerator()
{
for(int i=count-1;i>=0;--i)
{
yield return items[i];
}
}
}
使用foreach语句:
Stack<int> stack = new Stack<int>();
foreach(int i in statck){...}
使用迭代器创建倒序遍历:
public IEnumerable<T> BottomToTop
{
get
{
for(int i=0;i<count;i++)
{
yield return items[i];
}
}
}
迭代器中的yield语句
使用yield return 产生枚举元素:
for(int i=count-1;i>=0;--i)
{
yield return items[i];
}
使用yield break中断迭代:
for(int i=count-1;i>=0;--i)
{
yield return items[i];
if(items[i]>10)
yield break;
}
迭代器的机制
C# 2.0中的迭代器同样是通过编译器的一层额外处理,来简化创建可用于foreach的枚举集合的工作。
通过ILDasm.exe反汇编工作,我们可以获得对迭代器的深入理解:
- 迭代器中的GetEnumerator()方法
- 迭代器中的嵌套类
- 迭代器中的yield语句
总结
匿名方法允许我们以一种“内联”的方式将代码直接与委托实例相关联,从而使得委托实例化的工作更加直观和方便。迭代器允许我们更加方便地编写应用于foreach语句的枚举集合。
对于类似于C#这样的高级语言,掌握好它一个很重要的地方就是掌握编译器在背后为我们做了哪些工作。C# 2.0中的匿名方法和迭代器都是用国在编译层面进行一些额外的处理,进而来简化程序员的工作。