转载自:http://hi.baidu.com/algorithmanlxl/item/d94211d17a831c2039f6f792
这里的研究是借助了http://jangmon.blogbus.com/logs/36380490.html的帮助,虽然其中有些代码出现了错误,而且颇多细节没说清楚,但是对鄙人的启发意义很大。各位可以去该链接学习一下。而事实上,由于C#在.net框架中的高级特性和技术内幕很难深层次的说清楚,有些东西鄙人也是不甚明了。具体的接口说明和解释可以看看上面那篇博文,在这里我是想说说困扰很多人的"yield return”问题,到底其作用是怎么发挥的?我是用单步调试将其大概的调用顺序摸清楚的。先给出源程序,诸君可将其复制建立工程然后对比。
class Program { static void Main(string[] args) { HelloCollection helloCollection = new HelloCollection(); foreach (string s in helloCollection) Console.WriteLine(s); Console.ReadKey(); } //public class HelloCollection : IEnumerable //{ // public IEnumerator GetEnumerator() // { // yield return "Hello"; // yield return "World"; // } //} public class HelloCollection : IEnumerable { public IEnumerator GetEnumerator() { Enumerator enumerator = new Enumerator(0); return enumerator; } public class Enumerator : IEnumerator, IDisposable { private int state; private object current; public Enumerator(int state) { this.state = state; } public bool MoveNext() { switch (state) { case 0: current = "Hello"; state = 1; return true; case 1: current = "World"; state = 2; return true; case 2: break; } return false; } public void Reset() { throw new NotSupportedException(); } public object Current { get { return current; } } public void Dispose() { } } } }
上面注释的部分引用了"yield return”,其功能相当于下面所有代码!为什么呢,其实要从底层来说也很难解释得清楚,大家可以在foreach之前设一个断点,然后调试运行,会发现断点运行到foreach那一行的时候,会先编译"helloCollection",然后跳到下面的public IEnumerator GetEnumerator()执行该函数,而函数中原本的yield return会为HelloCollection类自动生成代码,就是多了Enumerator这个内部类的实现,且public IEnumerator GetEnumerator()里面的代码也会变成
Enumerator enumerator = new Enumerator(0);
return enumerator;
那么在运行到Enumerator enumerator = new Enumerator(0);的时候就会发现又跳到了Enumerator内部类的构造函数,构造完成后,回去编译foreach那行的"in",会发现又跳到了MoveNext函数,执行完毕后再去编译foreach那行的"string s”,发现跳到了Current字段的定义,调用了get方法,其内部估计是对s执行了赋值,不确定(暂且这样理解)。以此类推,最后会发现直到执行MoveNext返回了false,那么就会跳到了Dispose(),最后就这样了。
上面讲述的是通过断点来分析其运行的,而事实上如果比较简洁地去说的话,foreach这一行会被编译成IEnumerator e=helloCollection.GetEnumerator(),并自动生成一个while(e.MoveNext())循环实现了整个聚合的遍历。
本文转载自:http://hi.baidu.com/algorithmanlxl/item/d94211d17a831c2039f6f792