locked
Looping through custom collection classes. RRS feed

  • Question

  • I have a custom collection class. The main member of the class is a List(Of T). I did what this article says:

    http://support.microsoft.com/kb/322022

    For some reason though I can only foreach my collection once. The second time it tries it goes out of range because the position does not reset after the first foreach. What am I doing wrong?

     

    Public Class RoutePointCollection : Implements IEnumerable, IEnumerator

    #Region "Members"

        Private _position As Int32
        Private _routePoints As List(Of RoutePoint)

    #End Region

    #Region "Constructors"

        Public Sub New()
            _routePoints = New List(Of RoutePoint)
            _position = -1
        End Sub

    #End Region

     

    #Region "IEnumerable implementation"

        Public Function GetEnumerator() As System.Collections.IEnumerator Implements System.Collections.IEnumerable.GetEnumerator
            Return CType(Me, IEnumerator)
        End Function

    #End Region

    #Region "IEnumerator implemetation"

        Public ReadOnly Property Current As Object Implements System.Collections.IEnumerator.Current
            Get
                Return _routePoints(_position)
            End Get
        End Property

        Public Function MoveNext() As Boolean Implements System.Collections.IEnumerator.MoveNext
            _position += 1
            Return (_position < _routePoints.Count)
        End Function

        Public Sub Reset() Implements System.Collections.IEnumerator.Reset
            _position = -1
        End Sub

    #End Region

    End Class

    Wednesday, October 5, 2011 9:12 PM

Answers

  • It should be like this:

     

    Class RoutePointCollection : Implements IEnumerable
    
        Private _routePoints As List(Of RoutePoint)
    
    
        Public Function GetEnumerator() As System.Collections.IEnumerator Implements System.Collections.IEnumerable.GetEnumerator
            Return New Enumerator(_routePoints)
        End Function
    
        Private Class Enumerator : Implements IEnumerator
    
            Private _Position As Integer = -1
            Private InternalRoutePoint As List(Of RoutePoint)
    
            Public Sub New(ByVal Lst As List(Of RoutePoint))
                InternalRoutePoint = Lst
            End Sub
    
            Public ReadOnly Property Current() As Object Implements System.Collections.IEnumerator.Current
                Get
                    Return InternalRoutePoint(_Position)
                End Get
            End Property
    
            Public Function MoveNext() As Boolean Implements System.Collections.IEnumerator.MoveNext
                _Position += 1
                Return _Position < InternalRoutePoint.Count
    
            End Function
    
            Public Sub Reset() Implements System.Collections.IEnumerator.Reset
                _Position = -1
            End Sub
        End Class
    End Class

     

    • Edited by Crazypennie Wednesday, October 5, 2011 9:52 PM
    • Marked as answer by mscheaf Wednesday, October 5, 2011 10:06 PM
    Wednesday, October 5, 2011 9:50 PM

All replies

  • It should be like this:

     

    Class RoutePointCollection : Implements IEnumerable
    
        Private _routePoints As List(Of RoutePoint)
    
    
        Public Function GetEnumerator() As System.Collections.IEnumerator Implements System.Collections.IEnumerable.GetEnumerator
            Return New Enumerator(_routePoints)
        End Function
    
        Private Class Enumerator : Implements IEnumerator
    
            Private _Position As Integer = -1
            Private InternalRoutePoint As List(Of RoutePoint)
    
            Public Sub New(ByVal Lst As List(Of RoutePoint))
                InternalRoutePoint = Lst
            End Sub
    
            Public ReadOnly Property Current() As Object Implements System.Collections.IEnumerator.Current
                Get
                    Return InternalRoutePoint(_Position)
                End Get
            End Property
    
            Public Function MoveNext() As Boolean Implements System.Collections.IEnumerator.MoveNext
                _Position += 1
                Return _Position < InternalRoutePoint.Count
    
            End Function
    
            Public Sub Reset() Implements System.Collections.IEnumerator.Reset
                _Position = -1
            End Sub
        End Class
    End Class

     

    • Edited by Crazypennie Wednesday, October 5, 2011 9:52 PM
    • Marked as answer by mscheaf Wednesday, October 5, 2011 10:06 PM
    Wednesday, October 5, 2011 9:50 PM
  • Yep that worked, thanks alot. Do you know why doing at as the KB article showed produced a non-working result?
    Wednesday, October 5, 2011 10:06 PM
  • Because the enumerator is reused instead of being a new object ... So it is not reset
    Wednesday, October 5, 2011 10:09 PM
  • Oh. Seems I should have read all the way to the bottom of the article where it says "Implement IEnumerator in a nested class so that you can create multiple enumerators."

     

     

    Silly me! Thanks for your help, lifesaver!

    Wednesday, October 5, 2011 10:23 PM