C# translates the yield keyword into a state machine at compile time. VB.Net does not have the yield keyword, but it does have it's own mechanism for safely embedding state within a function that is not easily available in C#.
The C# static
keyword is normally translated to VB using the Shared
keyword, but there are two places where things get confusing. One is that a C# static class is really a Module in VB rather than a Shared class (you'd think they'd let you code it either way in vb, but noooo). The other is that VB.Net does have it's own Static
keyword. However, Static
has a different meaning in VB.Net.
You use the Static
keyword in VB.Net to declare a variable inside a function, and when you do the variable retains it's state across function calls. This is different than just declaring a private static class member in C#, because a static function member in VB.Net is guaranteed to also be thread-safe, in that the compiler translates it to use the Monitor class at compile time.
So why write all this here? Well, it should be possible to build a re-usable generic Iterator<T>
class (or Iterator(Of T)
in VB.Net). In this class you would implement the state machine used by C#, with Yield()
and Break()
methods that correspond to the C# keywords. Then you could use a static instance (in the VB.Net sense) in a function so that it can ultimately do pretty much the same job as C#'s yield
in about the same amount of code (discarding the class implemenation itself, since it would be infinitely re-usable).
I haven't cared enough about Yield to attempt it myself, but it should be doable. That said, it's also far from trivial, as C# team member Eric Lippert calls this "the most complicated transformation in the compiler." I have also come to believe since I wrote the first draft of this over a year ago that it's not really possible in a meaningful way until Visual Studio 2010 comes out, as it would require sending a lambda to the Iterator class and so to be really practical we need .Net 4's support for multi-line lambdas.