Home All Groups Group Topic Archive Search About

Using For Each in a Custom collection class with hashtables

Author
11 Oct 2006 7:00 AM
Erick
I've created a class called Procs and a collection class called
Processes which uses a hastable object to store the Procs.

Now i want to enumerate with the "For each" to extract all the Procs in
my Processes class.  As far as i can tell i need to implement an
IEnuerator method to do this.  But how ?

'Procs Class
Public Class Procs
    Private _Id As Integer
    Private _AppName As String
    Private _Owner As String
    Private _StartTime As DateTime
    Friend Property Id()
        Get
            Return _Id
        End Get
        Set(ByVal Value)
            _Id = Value
        End Set
    End Property
    Friend Property AppName()
        Get
            Return _AppName
        End Get
        Set(ByVal Value)
            _AppName = Value
        End Set
    End Property
    Friend Property Owner()
        Get
            Return _Owner
        End Get
        Set(ByVal Value)
            _Owner = Value
        End Set
    End Property
    Friend Property StartTime()
        Get
            Return _StartTime
        End Get
        Set(ByVal Value)
            _StartTime = Value
        End Set
    End Property

End Class



'processes class
Imports System.Collections
Public Class Processes
    Private _Processes As New Hashtable
    Friend Function Add(ByVal Proc As Procs)
        _Processes.Add(Proc.Id, Proc)
    End Function
    Friend Function Item(ByVal Id As Integer) As Procs
        Return _Processes.Item(Id)
    End Function

    Public Function GetEnumerator() As IEnumerator
        Return _Processes.GetEnumerator()
    End Function

End Class

' test call from a form load event
       Dim y As New Procs
        Dim v As New Procs
        Dim z As New Processes
        y.Id = 1
        y.AppName = "hello"
        v.Id = 2
        v.AppName = 2
        z.Add(y)
        z.Add(v)
        Dim q As Procs
        For Each q In z
            MsgBox(q.Id + "  " + q.AppName)
        Next

The for each loop won't work because Ienumerate has not been
implemented. But I can't find the correct code to do this. Can some one
fill in the code ?
I'm using .net 1.1

Erick

Author
11 Oct 2006 9:37 AM
Robinson
Hi Eric,

You can use For Each on the Values or Keys collection of the hashtable.
Also, I'm not sure if you know about generics, but it's preferable to use
them instead of hashtables where you know the type of object you are
storing.  So, for enumeration:


For Each theKey as Integer In MyHashtable.Keys

Next



For Each theValue As MyObject In MyHashtable.Values

Next




For Generics, look up the Dictionary type.  You can then make a Dictionary
(of Key, Value ), which is better for type checking at compile time.
Author
11 Oct 2006 9:45 AM
Robinson
Sorry, a simpler explaination would be to expose the Values collection of
the private hashtable you have there and iterate that:

For Each q As Procs In z.Values
           MsgBox(q.Id + "  " + q.AppName)
Next







Show quoteHide quote
"Robinson" <toomuchspamhaspassed@myinboxtoomuchtoooften.com> wrote in
message news:egidvu$kb3$1$8302bc10@news.demon.co.uk...
>
> Hi Eric,
>
> You can use For Each on the Values or Keys collection of the hashtable.
> Also, I'm not sure if you know about generics, but it's preferable to use
> them instead of hashtables where you know the type of object you are
> storing.  So, for enumeration:
>
>
> For Each theKey as Integer In MyHashtable.Keys
>
> Next
>
>
>
> For Each theValue As MyObject In MyHashtable.Values
>
> Next
>
>
>
>
> For Generics, look up the Dictionary type.  You can then make a Dictionary
> (of Key, Value ), which is better for type checking at compile time.
>
>
>
>
>
>
>
Author
11 Oct 2006 10:10 AM
Peter Macej
You need to create your own enumerator class and add
IEnumerable_GetEnumerator and GetEnumerator methods to your collection
class. See the first code listing on my blog at
http://www.helixoft.com/blog/archives/17 for details.

--
Peter Macej
Helixoft - http://www.helixoft.com
VSdocman - Commenter and generator of class documentation for C#, VB
..NET and ASP .NET code
Author
12 Oct 2006 3:15 AM
Erick
Yes, but how ?
Can you show me some sample code where they have used a hashtable and
then written an enumerator class for it ?

Erick

Peter Macej wrote:
Show quoteHide quote
> You need to create your own enumerator class and add
> IEnumerable_GetEnumerator and GetEnumerator methods to your collection
> class. See the first code listing on my blog at
> http://www.helixoft.com/blog/archives/17 for details.
>
> --
> Peter Macej
> Helixoft - http://www.helixoft.com
> VSdocman - Commenter and generator of class documentation for C#, VB
> .NET and ASP .NET code
Author
12 Oct 2006 12:16 AM
Dennis
I use something like this:

Public NotInheritable Class myCollection
    Implements ICollection

    Private collectArray As string() = {}
    Private CT as integer

    Sub New()
        Ct = 0
    End Sub

    Default Overloads ReadOnly Property Item(ByVal index As Integer) As
MultiTableStyle
        Get
            If index >= 0 AndAlso index <= Ct - 1 AndAlso Ct >= 1 Then
                Return collectArray(index)
            Else
                Return Nothing
            End If
        End Get
    End Property

    Public Sub Add(ByVal newString As String)
        collectArray(Ct) = newstring

        If UBound(collectArray) <= Ct Then ReDim Preserve
collectArray(UBound(collectArray) + CT)
        collectArray(Ct) = newStyle
        Ct = Ct + 1
    End Sub

    Public Overloads Sub Remove(ByVal indexToRemove As Integer)

    End Sub


    'The IsSynchronized Boolean property returns True if the collection is
designed to be thread safe; otherwise, it returns False.
    Public ReadOnly Property IsSynchronized() As Boolean Implements
ICollection.IsSynchronized
        Get
            Return False
        End Get
    End Property

    'The SyncRoot property returns an object, which is used to synchronize
    'the collection. This should return the instance of the object or return the
    'SyncRoot of another collection if the collection contains other collections.
    '
    Public ReadOnly Property SyncRoot() As Object Implements ICollection.SyncRoot
        Get
            Return Me
        End Get
    End Property

    'The ReadOnly property Count returns the number of items in the custom
collection.
    Public ReadOnly Property Count() As Integer Implements ICollection.Count
        Get
            Return Ct
        End Get
    End Property

    Public Function GetEnumerator() As IEnumerator Implements
ICollection.GetEnumerator
        Return New MultiTableStylesEnumerator(collectArray)
    End Function

    Private Sub CopyTo(ByVal myArr As Array, ByVal index As Integer) Implements
ICollection.CopyTo
        'Dummy for Icollection - Not implemented in this Class
    End Sub

End Class

'Enumerator for MyCollection Collection Class
Friend Class MultiTableStylesEnumerator
    Implements IEnumerator

    Private collectArray() As MultiTableStyle
    Private Cursor As Integer

    Sub New(ByVal collectArray() As MultiTableStyle)
        Me.collectArray = collectArray
        Cursor = -1
    End Sub
    Public Sub Reset() Implements IEnumerator.Reset
        Cursor = -1
    End Sub

    Public Function MoveNext() As Boolean Implements IEnumerator.MoveNext
        If Cursor < collectArray.Length Then
            Cursor = Cursor + 1
        End If
        If (Cursor = collectArray.Length) Then
            Return False
        Else
            Return True
        End If
    End Function
    Public ReadOnly Property Current() As Object Implements IEnumerator.Current
        Get
            If ((Cursor < 0) Or (Cursor = collectArray.Length)) Then
                Throw New InvalidOperationException
            Else
                Return collectArray(Cursor)
            End If
        End Get
    End Property

End Class
--
Dennis in Houston


Show quoteHide quote
"Erick" wrote:

> I've created a class called Procs and a collection class called
> Processes which uses a hastable object to store the Procs.
>
> Now i want to enumerate with the "For each" to extract all the Procs in
> my Processes class.  As far as i can tell i need to implement an
> IEnuerator method to do this.  But how ?
>
> 'Procs Class
> Public Class Procs
>     Private _Id As Integer
>     Private _AppName As String
>     Private _Owner As String
>     Private _StartTime As DateTime
>     Friend Property Id()
>         Get
>             Return _Id
>         End Get
>         Set(ByVal Value)
>             _Id = Value
>         End Set
>     End Property
>     Friend Property AppName()
>         Get
>             Return _AppName
>         End Get
>         Set(ByVal Value)
>             _AppName = Value
>         End Set
>     End Property
>     Friend Property Owner()
>         Get
>             Return _Owner
>         End Get
>         Set(ByVal Value)
>             _Owner = Value
>         End Set
>     End Property
>     Friend Property StartTime()
>         Get
>             Return _StartTime
>         End Get
>         Set(ByVal Value)
>             _StartTime = Value
>         End Set
>     End Property
>
> End Class
>
>
>
> 'processes class
> Imports System.Collections
> Public Class Processes
>     Private _Processes As New Hashtable
>     Friend Function Add(ByVal Proc As Procs)
>         _Processes.Add(Proc.Id, Proc)
>     End Function
>     Friend Function Item(ByVal Id As Integer) As Procs
>         Return _Processes.Item(Id)
>     End Function
>
>     Public Function GetEnumerator() As IEnumerator
>         Return _Processes.GetEnumerator()
>     End Function
>
> End Class
>
> ' test call from a form load event
>        Dim y As New Procs
>         Dim v As New Procs
>         Dim z As New Processes
>         y.Id = 1
>         y.AppName = "hello"
>         v.Id = 2
>         v.AppName = 2
>         z.Add(y)
>         z.Add(v)
>         Dim q As Procs
>         For Each q In z
>             MsgBox(q.Id + "  " + q.AppName)
>         Next
>
> The for each loop won't work because Ienumerate has not been
> implemented. But I can't find the correct code to do this. Can some one
> fill in the code ?
> I'm using .net 1.1
>
> Erick
>
>
Author
12 Oct 2006 3:19 AM
Erick
Dennis,
        your example does not use hashtables.  I need to find out how
to do a four each on a custom collection class which stores objects in
side a hastable.

Erick
Dennis wrote:
Show quoteHide quote
> I use something like this:
>
> Public NotInheritable Class myCollection
>     Implements ICollection
>
>     Private collectArray As string() = {}
>     Private CT as integer
>
>     Sub New()
>         Ct = 0
>     End Sub
>
>     Default Overloads ReadOnly Property Item(ByVal index As Integer) As
> MultiTableStyle
>         Get
>             If index >= 0 AndAlso index <= Ct - 1 AndAlso Ct >= 1 Then
>                 Return collectArray(index)
>             Else
>                 Return Nothing
>             End If
>         End Get
>     End Property
>
>     Public Sub Add(ByVal newString As String)
>         collectArray(Ct) = newstring
>
>         If UBound(collectArray) <= Ct Then ReDim Preserve
> collectArray(UBound(collectArray) + CT)
>         collectArray(Ct) = newStyle
>         Ct = Ct + 1
>     End Sub
>
>     Public Overloads Sub Remove(ByVal indexToRemove As Integer)
>
>     End Sub
>
>
>     'The IsSynchronized Boolean property returns True if the collection is
> designed to be thread safe; otherwise, it returns False.
>     Public ReadOnly Property IsSynchronized() As Boolean Implements
> ICollection.IsSynchronized
>         Get
>             Return False
>         End Get
>     End Property
>
>     'The SyncRoot property returns an object, which is used to synchronize
>     'the collection. This should return the instance of the object or return the
>     'SyncRoot of another collection if the collection contains other collections.
>     '
>     Public ReadOnly Property SyncRoot() As Object Implements ICollection.SyncRoot
>         Get
>             Return Me
>         End Get
>     End Property
>
>     'The ReadOnly property Count returns the number of items in the custom
> collection.
>     Public ReadOnly Property Count() As Integer Implements ICollection.Count
>         Get
>             Return Ct
>         End Get
>     End Property
>
>     Public Function GetEnumerator() As IEnumerator Implements
> ICollection.GetEnumerator
>         Return New MultiTableStylesEnumerator(collectArray)
>     End Function
>
>     Private Sub CopyTo(ByVal myArr As Array, ByVal index As Integer) Implements
> ICollection.CopyTo
>         'Dummy for Icollection - Not implemented in this Class
>     End Sub
>
> End Class
>
> 'Enumerator for MyCollection Collection Class
> Friend Class MultiTableStylesEnumerator
>     Implements IEnumerator
>
>     Private collectArray() As MultiTableStyle
>     Private Cursor As Integer
>
>     Sub New(ByVal collectArray() As MultiTableStyle)
>         Me.collectArray = collectArray
>         Cursor = -1
>     End Sub
>     Public Sub Reset() Implements IEnumerator.Reset
>         Cursor = -1
>     End Sub
>
>     Public Function MoveNext() As Boolean Implements IEnumerator.MoveNext
>         If Cursor < collectArray.Length Then
>             Cursor = Cursor + 1
>         End If
>         If (Cursor = collectArray.Length) Then
>             Return False
>         Else
>             Return True
>         End If
>     End Function
>     Public ReadOnly Property Current() As Object Implements IEnumerator.Current
>         Get
>             If ((Cursor < 0) Or (Cursor = collectArray.Length)) Then
>                 Throw New InvalidOperationException
>             Else
>                 Return collectArray(Cursor)
>             End If
>         End Get
>     End Property
>
> End Class
> --
> Dennis in Houston
>
>
> "Erick" wrote:
>
> > I've created a class called Procs and a collection class called
> > Processes which uses a hastable object to store the Procs.
> >
> > Now i want to enumerate with the "For each" to extract all the Procs in
> > my Processes class.  As far as i can tell i need to implement an
> > IEnuerator method to do this.  But how ?
> >
> > 'Procs Class
> > Public Class Procs
> >     Private _Id As Integer
> >     Private _AppName As String
> >     Private _Owner As String
> >     Private _StartTime As DateTime
> >     Friend Property Id()
> >         Get
> >             Return _Id
> >         End Get
> >         Set(ByVal Value)
> >             _Id = Value
> >         End Set
> >     End Property
> >     Friend Property AppName()
> >         Get
> >             Return _AppName
> >         End Get
> >         Set(ByVal Value)
> >             _AppName = Value
> >         End Set
> >     End Property
> >     Friend Property Owner()
> >         Get
> >             Return _Owner
> >         End Get
> >         Set(ByVal Value)
> >             _Owner = Value
> >         End Set
> >     End Property
> >     Friend Property StartTime()
> >         Get
> >             Return _StartTime
> >         End Get
> >         Set(ByVal Value)
> >             _StartTime = Value
> >         End Set
> >     End Property
> >
> > End Class
> >
> >
> >
> > 'processes class
> > Imports System.Collections
> > Public Class Processes
> >     Private _Processes As New Hashtable
> >     Friend Function Add(ByVal Proc As Procs)
> >         _Processes.Add(Proc.Id, Proc)
> >     End Function
> >     Friend Function Item(ByVal Id As Integer) As Procs
> >         Return _Processes.Item(Id)
> >     End Function
> >
> >     Public Function GetEnumerator() As IEnumerator
> >         Return _Processes.GetEnumerator()
> >     End Function
> >
> > End Class
> >
> > ' test call from a form load event
> >        Dim y As New Procs
> >         Dim v As New Procs
> >         Dim z As New Processes
> >         y.Id = 1
> >         y.AppName = "hello"
> >         v.Id = 2
> >         v.AppName = 2
> >         z.Add(y)
> >         z.Add(v)
> >         Dim q As Procs
> >         For Each q In z
> >             MsgBox(q.Id + "  " + q.AppName)
> >         Next
> >
> > The for each loop won't work because Ienumerate has not been
> > implemented. But I can't find the correct code to do this. Can some one
> > fill in the code ?
> > I'm using .net 1.1
> >
> > Erick
> >
> >