技术开发 频道

.Net编程接口剖析系列之迭代器


Yield Return

    从前面我们可能发现,有时候写一个迭代器可能是挺麻烦的一个事情,其实需求却可能是挺简单的,但是我们却要写大量代码来实现一个迭代器。所幸的是,C#给我们提供一个独门利器:Yield Return! 利用yield return,我们不需要写一个迭代器就能够实现GetEnumerator函数了。
Yield return不同于普通函数的Return,它从作用上来说,相当于每调用一次yield return,就返回一个被枚举的元素。Yield Return语法只能用在返回值类型为IEnumerator的函数中。 我们现在来看看,List2D的GetEnumerator函数如何用yield return来实现,从而使我们不用再创建一个自定义的Emurator类型。
IEnumerator<T> IEnumerable<T>.GetEnumerator()
{
foreach (List<T> list in _lists)
{
foreach (T item in list)
{
yield return item;
}
}
}
    7行!包括4个花括弧仅仅用了7行代码,就实现了一个迭代器的所有功能,而前面我们为了实现一个迭代器,写了数十行的代码,这对编码效率上来说,这是多么大的一个提升啊。当然,并非所有情形下,用yield return都是合适,但是在一般的需求之下,它是最好的选择。
习惯了传统编程语言的人,可能会比较难易理解Yield Return这个东西,而且更会对它是到底是如何实现的充满了疑问。其实Yield Return是C#从语言层面上提供的一种简化代码的语法形式而已,而归根到底,其实是C#的编译器辅助我们完成了一部分编码工作—它为我们自动创建了一个匿名的迭代器类型,并且用那个迭代器实现了我们在使用yield return语义所实现的迭代功能。
    如果你对上面的论断产生怀疑的话,我们可以借助VS.net自带的IL查看工具ildasm.exe来查看我们用yield return代码编译后的exe文件。Ildasm.exe (VS2005)通常存放在“C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bin\”目录下。
    从下面Ildasm.exe的截图中我们可以看见List2D类型中有个嵌套类型GetEnumerator>d__0<T>,而这个恰恰就是C#编译器为我们生成的匿名迭代器类型。

0
相关文章