tags:

views:

3561

answers:

7
+8  Q: 

Yield In VB.NET

C# has the keyword called yield. VB.NET lacks this keyword. I am curious how some of the VB programmers have gotten around the lack of this keyword. Do you implement your own iterator class? Or do you try and code to avoid the need of an iterator?

The yield keyword does force the compiler to do some coding behind the scenes. http://blogs.msdn.com/oldnewthing/archive/2008/08/12/8849519.aspx is a good example of that.

A: 

I personally just write my own iterator class that inherits from IEnumerator(Of T). It does take sometime to get it right, but I think in the end its better to write it right then try to avoid it. Another method that I have done is to write a recursive method that returns IEnumerable(Of T) and just returns List(Of T) and uses .AddRange.

MagicKat
I could really use something like that! Would you please post the code somewhere? Thanks
Mauricio Scheffer
A: 

I just use a For Each loop.

Joel Coehoorn
A: 

Yield is cool and all, but it's not that much more effective than something like this...

Public Function GetValues() As SomeType()
    Dim results As List(Of SomeType)
    For Each item In someCollection
        If ItemIsOkay(item) Then results.Add(item)
    Next
    Return results.ToArray()
End Function

It works well enough and it's not that much more code.

Hugoware
Actually it's *fundamentally* different: yield evaluates lazily, this code does not
Mauricio Scheffer
Do While True: i = i+1: Yield i: Loop
recursive
Linked my mistake to a blog post -- looks like I'll be paying for it here :)
Hugoware
You completely misunderstand what yield is for. The yield keyword is significantly more effective than your ToArray example... Yield is what gives Linq much of its power. Without it, Linq would have been significantly more difficult to write... (custom iterators for everything)
Brian Genisio
Yes, I did - I wrote a blog post explaining my screw up - I thought that it was funny that I escaped with no downvotes for all that time. :)
Hugoware
+18  A: 

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.

Joel Coehoorn
Wish I could vote the answer more than once! Nice Answer!
Kirtan
A: 

Hopefully, this will be a thing of the past with the upcoming version of VB. Since iterators are actually gaining a lot of importance with new paradigms (especially LINQ in combination with lazy evaluation), this has quite a high priority, as far as I know from Paul Vick's blog. Then again, Paul's no longer the head of the VB team and I haven't yet had time to watch the PCD talks.

Still, if you're interested, they're linked in Paul's blog.

Konrad Rudolph
A: 

I wish I had seen this post last month! I was a member of a 300 person team working on a huge application for a major client. The codebase was around 400,000 lines. We had been working on the application for 18 months, and were just doing some final QA, when we realized we needed the YIELD keyword for a particular loop. We had to recode the entire application in C# and it wound up costing our company nearly one million dollars.

Shawn Simon
That's silly: you can have C# and VB in the same application. Just abstract the method or class in question to it's own class library.
Joel Coehoorn
now you tell me!
Shawn Simon
And you work for a company spending millions of dollars? scary
Harry
what the... tell me you're joking?? In what kind of situation would the yield keyword be that important? And you can write your own iterator instead of using Yield, it would cost maybe two man-hours instead of a million dollars. And as Joel said, you could have used C# code for that particular part :S
Meta-Knight
Sounds like a put-on to me.
Robert Harvey
+2  A: 

There's this nice article by Bill McCarthy in Visual Studio magazine on emulating yield in VB.NET. Alternatively wait for the next version of VB.

MarkJ