Use Iterators in VB Now: VB: Create a GenericIterator class: Listing 2
This class is most useful in VB10, where you can pass in a multi-statement lamba expression for the MoveNextFunc. You can use this generic template in VB8 and VB9, but without support for multi-statement lambdas you'll find that you'll need to use AddressOf, and capture variables used by making them fields of a wrapper class. As a consequence, you're better off using the direct implementation (Listing 1) rather than the generic template for versions of VB prior to VB10.
Public Class GenericIterator(Of T)
Implements IEnumerable(Of T)
Implements IEnumerator(Of T)
Public Delegate Function MoveNextFunc( _
ByRef nextItem As T) As Boolean
Private _Current As T
Private _func As MoveNextFunc
Public Sub New(ByVal func As MoveNextFunc)
_func = func
End Sub
Public Function MoveNext() As Boolean _
Implements IEnumerator.MoveNext
Return _func(_Current)
End Function
Public Function GetEnumerator() _
As IEnumerator(Of T) _
Implements IEnumerable(Of T).GetEnumerator
Static iBeenCalled As Int32
If (iBeenCalled = 0) AndAlso _
(Threading.Interlocked.Increment( _
iBeenCalled) = 1) Then
Return Me
Else
Return New GenericIterator(Of T)(_func)
End If
End Function
Public ReadOnly Property Current() As T _
Implements IEnumerator(Of T).Current
Get
Return _Current
End Get
End Property
Public Overridable Sub Reset() _
Implements IEnumerator.Reset
Throw New NotImplementedException( _
"Iterator cannot be reset")
End Sub
Private Function _
IEnumerator_GetEnumerator() As IEnumerator _
Implements IEnumerable.GetEnumerator
Return Me.GetEnumerator
End Function
Private ReadOnly Property IEnumerator_Current() _
As Object Implements IEnumerator.Current
Get
Return Me.Current
End Get
End Property
Public Sub Dispose() _
Implements IDisposable.Dispose
' not implemented
End Sub
End Class