VB.NET's "yield return"

I was struggling with an issue today when converting some C# to VB.NET. C# has a really cool "yield return" statement that is used in an iterator block to provide a value to the enumerator object. VB.NET does not have the "yield" keyword. So, there are a few solutions (none of which are really clean) to get around this. You could use a return statement to return the value if you are looping through and would like to break an enumerator and return a single value. However, if you'd like to return the entire enumeration, create a List() of the child type and return the list. Since you are usually using this with an IEnumerable, the List() will work nice.

10 Comments

  • If the function returns IEnumerable(Of String) your return statement (which is the equivalent of yield return "MyReturnValue") would be:

    Return New String() {"MyReturnValue"}

    Or, instead of String it could be any enumerable type.

  • Public Shared Function ReadLinesFromFile(ByVal fileName As String) As IEnumerable(Of String)
    Dim stringList As New List(Of String)

    Using reader As StreamReader = New StreamReader(fileName)
    Dim s As String

    While True
    s = reader.ReadLine
    If s Is Nothing Then
    Exit While
    Else
    stringList.Add(s)
    End If
    End While

    End Using

    Return stringList

    End Function

  • That works if you're returning an IEnumerable(Of T), but not if you're returning an IEnumerator(Of T). In that case, return your list but tack on the GetEnumerator() function to the end. i.e. Return myList.GetEnumerator()

  • isnt that defeating the purpose of "yield return" for lazy evaluating.

  • C# code

    public IEnumerator GetEnumerator()
    {
    foreach (mList column in mItems)
    yield return column;
    yield break;
    }

    VB.NET code

    Public Function GetEnumerator() As IEnumerator(Of mList)_ Implements IEnumerable(Of mList).GetEnumerator Return mItems.GetEnumerator
    End Function

  • In the VB.NET 10, you could use :

    Return New List(Of mList) From {mItems}

  • Vb net s quot yield return quot.. Bully :)

  • Yield is syntactic sugar. Behind the scenes it returns an IEnumerator instance that handles the callbacks into your function. To do the lazy enumeration, you have to implement it yourself unfortunately.

  • And how does that mean? I do not understand anything.

  • The Compiler generates a class for yield return you could decompile it and build it to use it.
    It would look like this..
    Public ReadOnly Property Properties As IEnumerable(Of IProperty)
    Get
    Dim x = New get_Propertiesd__18(-2)
    x._This = Me
    Return x
    End Get
    End Property

    Private NotInheritable Class get_Propertiesd__18
    Implements IEnumerable(Of IProperty), IEnumerator(Of IProperty)
    ' Fields
    Private _State As Integer
    Private _Current As IProperty
    Public _This As DefaultResolvedTypeDefinition
    Private _InitialThreadId As Integer

    Public i5__1a As Integer
    Public members5__19 As MemberList
    ' Methods
    Public Sub New(ByVal state As Integer)
    _State = state
    _InitialThreadId = Thread.CurrentThread.ManagedThreadId
    End Sub
    '
    #Region "IEnumerable(Of IProperty) Support"
    ' Methods
    Private Function GetEnumerator2() As System.Collections.Generic.IEnumerator(Of IProperty) Implements System.Collections.Generic.IEnumerable(Of IProperty).GetEnumerator
    If ((Thread.CurrentThread.ManagedThreadId = _InitialThreadId) AndAlso (_State = -2)) Then
    _State = 0
    Return Me
    End If
    Return New get_Propertiesd__18(0) With { _
    ._This = Me._This _
    }
    End Function
    '
    #End Region
    '
    #Region "IEnumerable Support"
    ' Methods
    Private Function GetEnumerator1() As System.Collections.IEnumerator Implements System.Collections.IEnumerable.GetEnumerator
    Return DirectCast(Me, IEnumerable(Of IProperty)).GetEnumerator()
    End Function
    '
    #End Region
    '
    #Region "IEnumerator(Of IProperty) Support"
    ' Properties
    Private ReadOnly Property Current2 As IProperty Implements System.Collections.Generic.IEnumerator(Of IProperty).Current
    Get
    Return _Current
    End Get
    End Property
    '
    #End Region
    '
    #Region "IEnumerator Support"
    ' Methods
    Public Function MoveNext1() As Boolean Implements System.Collections.IEnumerator.MoveNext
    Select Case _State
    Case 0
    _State = -1
    Me.members5__19 = Me._This.GetMemberList
    Me.i5__1a = 0
    Case 1
    _State = -1
    Me.i5__1a += 1
    Case Else
    Return False
    End Select
    '
    Do
    If (Me.i5__1a < Me.members5__19.FUnresolvedMembers.Length) Then
    Select Case Me.members5__19.FUnresolvedMembers(Me.i5__1a).EntityType
    Case EntityType.Property, EntityType.Indexer
    _Current = DirectCast(Me.members5__19.Item(Me.i5__1a), IProperty)
    _State = 1
    Return True
    End Select
    Me.i5__1a += 1
    Else
    Exit Do
    End If
    Loop
    '
    Return False
    End Function
    Public Sub Reset1() Implements System.Collections.IEnumerator.Reset
    Throw New NotSupportedException
    End Sub
    ' Properties
    Public ReadOnly Property Current1 As Object Implements System.Collections.IEnumerator.Current
    Get
    Return _Current
    End Get
    End Property
    '
    #End Region
    '
    #Region "IDisposable Support"
    ' Methods
    Private Sub Dispose1() Implements IDisposable.Dispose
    End Sub
    '
    #End Region
    '
    End Class

Comments have been disabled for this content.