Introduction 

This article demonstrates how to implement both IEnumerable(Of T) and IEnumerator(Of T) in VB.NET and use them to read data in a collection. 

Background

How can i do iteration over a collection? ....... for VB coders, almost the question has no answer, and if you search over the internet you might be lucky to find enough information which may answer your question in VB.net, actually C# coders are really lucky with Yield statement but VB.net Coders they must suffer a little .....

Build your Iterator

To Build your Iterator in VB.net you must implement both IEnumerator(Of T) and IEnumerable(Of T) eith in the same class or in two different classes....

The Below codes demonstrate how to build your own Generic iterator and use it with any collection> 

Implementation with List

''' <summary>
''' Copyright © Omar Amin Ibrahim 2011
''' silverlight1212@yahoo.com
''' </summary>
''' <typeparam name="T"></typeparam>
''' <remarks></remarks>
Public Class RiverNileListEnumerator(Of T)
    Implements IEnumerable(Of T)
    Implements IEnumerator(Of T)

#Region " Fields "

    Private _list As IList(Of T)
    Private _index As Integer
    Private _current As T

#End Region

#Region " Constructor "

    Public Sub New(ByVal list As IList(Of T))
        MyBase.New()
        _list = list
        _index = -1
        _current = CType(Nothing, T)
    End Sub

#End Region

#Region " Properties "

    Public ReadOnly Property Current As T Implements System.Collections.Generic.IEnumerator(Of T).Current
        Get
            If _current Is Nothing Then
                Throw New InvalidOperationException()
            End If

            Return _current
        End Get
    End Property

    Private ReadOnly Property System_Collections_Current As Object Implements System.Collections.IEnumerator.Current
        Get
            Return Me.Current
        End Get
    End Property

#End Region

#Region " Methods "

    Public Function GetEnumerator() As System.Collections.Generic.IEnumerator(Of T) Implements System.Collections.Generic.IEnumerable(Of T).GetEnumerator
        Return New RiverNileListEnumerator(Of T)(Me._list)
    End Function

    Private Function System_Collections_GetEnumerator() As System.Collections.IEnumerator Implements System.Collections.IEnumerable.GetEnumerator
        Return Me.GetEnumerator
    End Function

    Public Function MoveNext() As Boolean Implements System.Collections.IEnumerator.MoveNext
        _index = _index + 1
        If _index = _list.Count Then
            Return False
        Else
            _current = _list(_index)
        End If
        Return True
    End Function

    Public Sub Reset() Implements System.Collections.IEnumerator.Reset
        _index = -1
        _current = CType(Nothing, T)
    End Sub

    Private Sub System_IDisposable_Dispose() Implements IDisposable.Dispose
        ' do nothing
    End Sub

#End Region

End Class ' RiverNileListEnumerator
		 

Implementation with Collection

''' <summary>
''' Copyright © Omar Amin Ibrahim 2011
''' silverlight1212@yahoo.com
''' </summary>
''' <typeparam name="T"></typeparam>
''' <remarks></remarks>
Public Class RiverNileCollectionEnumerator(Of T)

    Implements IEnumerable(Of T)
    Implements IEnumerator(Of T)

#Region " Fields "

    Private _collectiont As ICollection(Of T)
    Private _index As Integer
    Private _current As T

#End Region

#Region " Constructor "

    Public Sub New(ByVal collection As ICollection(Of T))
        MyBase.New()
        _collectiont = collection
        _index = -1
        _current = CType(Nothing, T)
    End Sub

#End Region

#Region " Properties "

    Public ReadOnly Property Current As T
        Get
            If _current Is Nothing Then
                Throw New InvalidOperationException()
            End If

            Return _current
        End Get
    End Property

    Private ReadOnly Property System_Collections_Generic_Current As T Implements System.Collections.Generic.IEnumerator(Of T).Current
        Get
            Return Me.Current
        End Get
    End Property

    Private ReadOnly Property System_Collections_Current As Object Implements System.Collections.IEnumerator.Current
        Get
            Return Me.Current
        End Get
    End Property

#End Region

#Region " Methods "

    Public Function GetEnumerator() As IEnumerator(Of T)
        Return New RiverNileCollectionEnumerator(Of T)(Me._collectiont)
    End Function

    Public Function MoveNext() As Boolean
        _index = _index + 1
        If _index = _collectiont.Count Then
            Return False
        Else
            _current = _collectiont(_index)
        End If
        Return True
    End Function

    Public Sub Reset()
        _index = -1
        _current = CType(Nothing, T)
    End Sub

    Private Function System_Collections_Generic_GetEnumerator() As System.Collections.Generic.IEnumerator(Of T) Implements System.Collections.Generic.IEnumerable(Of T).GetEnumerator
        Return Me.GetEnumerator
    End Function

    Private Function System_Collections_GetEnumerator() As System.Collections.IEnumerator Implements System.Collections.IEnumerable.GetEnumerator
        Return Me.GetEnumerator
    End Function

    Private Function System_Collections_MoveNext() As Boolean Implements System.Collections.IEnumerator.MoveNext
        Return MoveNext()
    End Function

    Private Sub System_Collections_Reset() Implements System.Collections.IEnumerator.Reset
        Me.Reset()
    End Sub

    Private Sub System_IDisposable_Dispose() Implements IDisposable.Dispose
        ' do nothing
    End Sub

#End Region

End Class ' RiverNileCollectionEnumerator
		

Iterator 

''' <summary>
''' Copyright © Omar Amin Ibrahim 2011
''' silverlight1212@yahoo.com
''' </summary>
''' <remarks></remarks>
Public NotInheritable Class RiverNileGenerics

    Public Shared Function Iterator(Of T)(ByVal list As IList(Of T)) As RiverNileListEnumerator(Of T)
        If (list Is Nothing) Then
            Throw New ArgumentNullException("list")
        End If
        Return New RiverNileListEnumerator(Of T)(list)
    End Function

    Public Shared Function Iterator(Of T)(ByVal collection As ICollection(Of T)) As RiverNileCollectionEnumerator(Of T)
        If (collection Is Nothing) Then
            Throw New ArgumentNullException("collection")
        End If
        Return New RiverNileCollectionEnumerator(Of T)(collection)
    End Function

End Class ' RiverNileGenerics

Using the code

It is simple Try it.

    Imports RiverNile.RiverNileGenerics
    
    Public Class Form1
    
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    
            Dim ColorCollection As ICollection(Of KnownColor) = New List(Of KnownColor) From {KnownColor.Aqua, KnownColor.Red, KnownColor.Black}
            For Each clr As KnownColor In Iterator(ColorCollection)
                ListBox1.Items.Add(clr)
            Next
    
            Dim StringList As IList(Of String) = New List(Of String) From {"Omar", "Amin", "Ibrahim"}
            For Each Str As String In Iterator(StringList)
                ListBox2.Items.Add(Str)
            Next
    
        End Sub
    
    End Class
    

How To use it with a Collection  

1- Define your collection, inherits from collection base.

2- Implements IList(Of n). 

3- Just call the Iterator shared method from the RiverNileGenerics Class as below.

Imports RiverNile.RiverNileGenerics
Public Class BarCollection
    Inherits CollectionBase
    Implements IList(Of Bar)

#Region " Fields "

    Private owner As BarControl

#End Region

#Region " Constructor "

    Public Sub New(ByVal containerControl As BarControl)
        Me.owner = containerControl
    End Sub

#End Region

#Region " Methods "

    Public Overloads Function GetEnumerator() As IEnumerator(Of Bar)
        Return Iterator(Of Bar)(Me)
    End Function

    Private Function System_Collections_Generic_GetEnumerator() As System.Collections.Generic.IEnumerator(Of Bar) Implements System.Collections.Generic.IEnumerable(Of Bar).GetEnumerator
        Return Me.GetEnumerator
    End Function

    ' rest of the codes goes here

#End Region

End Class

History 

10th July, 2011: First release

推荐.NET配套的通用数据层ORM框架:CYQ.Data 通用数据层框架