C# has the keyword called yield. VB.NET lacks this keyword. How have the Visual Basic programmers gotten around the lack of this keyword? Do they implement they own iterator class? Or do they try and code to avoid the need of an iterator?
The yield keyword does force the compiler to do some coding behind the scenes. The implementation of iterators in C# and its consequences (part 1) has a good example of that.
Definition. expression. Required. An expression that is implicitly convertible to the type of the iterator function or Get accessor that contains the Yield statement.
You use a yield return statement to return each element one at a time. The sequence returned from an iterator method can be consumed by using a foreach statement or LINQ query. Each iteration of the foreach loop calls the iterator method.
The yield keyword is use to do custom stateful iteration over a collection. The yield keyword tells the compiler that the method in which it appears is an iterator block. yield return <expression>; yield break; The yield return statement returns one element at a time.
In the iterator block, the yield keyword is used together with the return keyword to provide a value to the enumerator object. This is the value that is returned, for example, in each loop of a foreach statement. The yield keyword is also used with break to signal the end of iteration."
C# translates the yield keyword into a state machine at compile time. VB.NET does not have the yield keyword, but it does have its own mechanism for safely embedding state within a function that is not easily available in C#.
The C# static
keyword is normally translated to Visual Basic 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 Visual Basic rather than a Shared class (you'd think they'd let you code it either way in Visual Basic, but noooo). The other is that VB.NET does have its 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 its 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 multiple lambdas to the Iterator class and so to be really practical we need .NET 4's support for multi-line lambdas.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With