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
         Return New GenericIterator(Of T)(_func)
      End If
   End Function

   Public ReadOnly Property Current() As T _
               Implements IEnumerator(Of T).Current
         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
         Return Me.Current
      End Get
   End Property

   Public Sub Dispose() _
      Implements IDisposable.Dispose
      ' not implemented
   End Sub

End Class
comments powered by Disqus


Upcoming Events