9

Possible Duplicate:
Yield In VB.NET

In C#, when writing a function that returns an IEnumerble<>, you can use yield return to return a single item of the enumeration and yield break; to signify no remaining items. What is the VB.NET syntax for doing the same thing?

An example from the NerdDinner code:

public IEnumerable<RuleViolation> GetRuleViolations() {

   if (String.IsNullOrEmpty(Title))
       yield return new RuleViolation("Title required","Title");

   if (String.IsNullOrEmpty(Description))
       yield return new RuleViolation("Description required","Description");

   if (String.IsNullOrEmpty(HostedBy))
       yield return new RuleViolation("HostedBy required", "HostedBy");

   if (String.IsNullOrEmpty(Address))
       yield return new RuleViolation("Address required", "Address");

   if (String.IsNullOrEmpty(Country))
       yield return new RuleViolation("Country required", "Country");

   if (String.IsNullOrEmpty(ContactPhone))
       yield return new RuleViolation("Phone# required", "ContactPhone");

   if (!PhoneValidator.IsValidNumber(ContactPhone, Country))
       yield return new RuleViolation("Phone# does not match country", "ContactPhone");

   yield break;
}

This convert C# to VB.NET tool gives a "YieldStatement is unsupported" error.

Community
  • 1
  • 1
CoderDennis
  • 13,642
  • 9
  • 69
  • 105
  • Note that yielding is not returning, at least not in the sense that most people mean returning (the way it is implemented under the hood notwithstanding). Also, you don't need yield break there. Also, you may want to think about transforming that code from yielding an enumeration of RuleViolation objects to yielding an enumeration of Func delegates. – yfeldblum May 17 '09 at 22:02
  • Using yield reminds me of piping in that calling code can start iterating through the ienumerable *before* the function returning the ienumerable has finished running. Very cool! – Neil Trodden May 17 '09 at 22:15
  • 2
    That's a terrible example, because you blatantly don't need yeild for something like that: what's the benefit of determining the rule violations lazily? Stuff them all in a list and be done with it. That's not to say yeild isn't useful, but this is just a bad example – piers7 Aug 14 '09 at 05:40
  • @piers7, I've learned a lot more about yield and iterators since I posted this question and I would have to agree with you. This was just the first place I had seen yield, so that's why I included that example. Best example I've seen to date is a prime number generator that doesn't have a pre-set size limit (other than MaxInt of course) – CoderDennis Aug 14 '09 at 14:51
  • Wow, 5 minutes into using VB and I've encounter a major issue. I wonder what else is missing. While I don't use yield return every day I do use the functions that it enables me to write every day. I'm off to tell management I'm not using VB on this one :-) I thought VB was meant to have caught up with C#. – MikeKulls Feb 02 '12 at 05:00
  • 1
    To piers7, I'm not sure it's such a bad example. It evaluates the conditions as required and stops if whatever is consuming it stops. – MikeKulls Feb 06 '12 at 00:16

6 Answers6

13

There is currently no equivalent to C#'s yield return in VB.Net from a language syntax level.

However there was a recent write up in MSDN magazine by Bill McCarthy on how to implement a similar pattern in VB.Net 9.0

JaredPar
  • 733,204
  • 149
  • 1,241
  • 1,454
8

The new Async CTP includes support for Yield in VB.NET.

See Iterators in Visual Basic for information on usage.

CoderDennis
  • 13,642
  • 9
  • 69
  • 105
2

See my answers here:

To summarize:
VB.Net does not have yield, but C# implements yield by converting your code to a state machine behind that scenes. VB.Net's Static keyword also allows you to store state within a function, so in theory you should be able to implement a class that allows you to write similar code when used as a Static member of a method.

Community
  • 1
  • 1
Joel Coehoorn
  • 399,467
  • 113
  • 570
  • 794
0

Below gives output: 2, 4, 8, 16, 32

In VB,

Public Shared Function setofNumbers() As Integer()

    Dim counter As Integer = 0
    Dim results As New List(Of Integer)
    Dim result As Integer = 1
    While counter < 5
        result = result * 2
        results.Add(result)
        counter += 1
    End While
    Return results.ToArray()
End Function

Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    For Each i As Integer In setofNumbers()
        MessageBox.Show(i)
    Next
End Sub

In C#

   private void Form1_Load(object sender, EventArgs e)
    {
        foreach (int i in setofNumbers())
        {
            MessageBox.Show(i.ToString());
        }
    }

    public static IEnumerable<int> setofNumbers()
    {
        int counter=0;
        //List<int> results = new List<int>();
        int result=1;
        while (counter < 5)
        {
          result = result * 2;
          counter += 1;
          yield return result;
        }
    }
CoderDennis
  • 13,642
  • 9
  • 69
  • 105
  • 2
    Yes, for this simple example, that would work. There are other better examples of iterators where you don't want to or cannot create the entire list within a single function call. Your C# code only calculates each value as you use them within the `foreach` loop. The VB code calculates all the values when you call the `setOfNumbers` function. That's a significant difference. – CoderDennis May 04 '11 at 16:02
0

No yield return in VB.NET :( Just create a list and return it.

bbmud
  • 2,678
  • 21
  • 15
0

Behind the scenes, the compiler creates an enumerator class to do the work. Since VB.NET does not implement this pattern, you have to create your own implementation of IEnumerator(Of T)

Thomas Levesque
  • 286,951
  • 70
  • 623
  • 758