yield关键字强制编译器在后台做一些编码。 The implementation of iterators in C# and its consequences (part 1)有一个很好的例子。
C#在编译时将yield关键字转换为状态机。 VB.NET没有yield关键字,但它有自己的机制,用于在C#中不容易获得的函数中安全地嵌入状态。
C#static关键字通常使用Shared关键字翻译为Visual Basic,但有两个地方的事情让人困惑。一个是C#静态类是Visual Basic中的一个模块,而不是一个Shared类(你会认为他们会让你在Visual Basic中编码,但noooo)。另一个是VB.NET有自己的Static关键字。然而,Static在VB.NET中有不同的含义。
你使用VB.NET中的Static关键字来声明一个函数内的变量,当你做的变量保持其状态跨函数调用。这不同于在C#中声明私有静态类成员,因为VB.NET中的静态函数成员也保证是线程安全的,因为编译器将它编译成在编译时使用Monitor类。
那么为什么要在这里写这一切?嗯,应该可以建立一个可重用的通用迭代器< T>类(或VB.NET中的Iterator(Of T))。在这个类中,你将实现C#使用的状态机,使用对应于C#关键字的Yield()和Break()方法。然后你可以在一个函数中使用一个静态实例(在VB.NET意义上),这样它最终可以做同样的工作作为C#的产量大约相同的代码(丢弃类实现本身,因为它将无限可重复使用)。
我没有足够关心Yield自己尝试,但它应该是可行的。也就是说,它也远不是微不足道,正如C#团队成员Eric Lippert称之为“the most complicated transformation in the compiler”。我也相信,因为我写了一年前的第一稿,直到Visual Studio 2010出来,它是不可能有一个有意义的方式,因为它需要发送多个lambdas到Iterator类,所以真的实际我们需要[.NET 43的支持多行lambdas。