Home All Groups Group Topic Archive Search About

URGENT: Problem when iterating through a custom collection (dictionary based) with FOR...EACH

Author
24 Jan 2006 8:13 AM
Martin Widmer
Hi folks.

I am using this collection class:

Public Class ContentBlocksCollection
    Inherits DictionaryBase
    'Object variables for attributes
    'Attributes
    Default Public Property Item(ByVal nDBKey As Long) As ContentBlock
        Get
            Return MyBase.Dictionary.Item(nDBKey)
        End Get
        Set(ByVal value As ContentBlock)
            MyBase.Dictionary.Item(nDBKey) = value
        End Set
    End Property
    'Methods
    Public Sub Add(ByVal oContentBlock As ContentBlock)
        MyBase.Dictionary.Add(oContentBlock.DBKey, oContentBlock)
    End Sub
    Public Sub Remove(ByVal nDBKey As Long)
        MyBase.Dictionary.Remove(nDBKey)
    End Sub
    Public Function Contains(ByVal nDBKey As Long) As Boolean
        Return MyBase.Dictionary.Contains(nDBKey)
    End Function
End Class

And now I want to iterate through it like this in the parent object holding
the collection:

    'Methods
    Public Function GetContentBlock(ByVal nDBKey As Long) As ContentBlock
        Dim oContentBlock As ContentBlock

        For Each oContentBlock In Me.ContentBlocks
            If oContentBlock.DBKey = nDBKey Then
                Return oContentBlock
            End If
        Next
        Return Nothing
    End Function

I always get this error at the "For Each..." line:
"Unable to cast object of type 'System.Collections.DictionaryEntry' to type
'ContentObjects.ContentBlock'."

I am using VS 2005
Why do I get this error? Is it not possible to use for...each...next with
custom collections based on DictionaryBase?

Martin

Author
24 Jan 2006 10:46 AM
Armin Zingler
Show quote Hide quote
"Martin Widmer" <martin.wid***@businessnet.de> schrieb
> Public Class ContentBlocksCollection
>    Inherits DictionaryBase
>
> [...]
>
> I always get this error at the "For Each..." line:
> "Unable to cast object of type 'System.Collections.DictionaryEntry'
> to type 'ContentObjects.ContentBlock'."
>
> I am using VS 2005
> Why do I get this error? Is it not possible to use for...each...next
> with custom collections based on DictionaryBase?


Read the "remakrs" section in the DictionaryBase documentation. Describes
exactly your problem.



Armin
Author
24 Jan 2006 10:52 AM
Ken Tucker [MVP]
Hi,

            The hash table inherits from dictionary base.  Each item is
stored with its key in an dictonary entry.

       Dim de As DictionaryEntry
        For Each de In ht
            Trace.WriteLine(de.Value)
        Next

Ken
----------------------
Show quoteHide quote
"Martin Widmer" <martin.wid***@businessnet.de> wrote in message
news:dr4on5$pe9$1@nntp.init7.net...
> Hi folks.
>
> I am using this collection class:
>
> Public Class ContentBlocksCollection
>    Inherits DictionaryBase
>    'Object variables for attributes
>    'Attributes
>    Default Public Property Item(ByVal nDBKey As Long) As ContentBlock
>        Get
>            Return MyBase.Dictionary.Item(nDBKey)
>        End Get
>        Set(ByVal value As ContentBlock)
>            MyBase.Dictionary.Item(nDBKey) = value
>        End Set
>    End Property
>    'Methods
>    Public Sub Add(ByVal oContentBlock As ContentBlock)
>        MyBase.Dictionary.Add(oContentBlock.DBKey, oContentBlock)
>    End Sub
>    Public Sub Remove(ByVal nDBKey As Long)
>        MyBase.Dictionary.Remove(nDBKey)
>    End Sub
>    Public Function Contains(ByVal nDBKey As Long) As Boolean
>        Return MyBase.Dictionary.Contains(nDBKey)
>    End Function
> End Class
>
> And now I want to iterate through it like this in the parent object
> holding the collection:
>
>    'Methods
>    Public Function GetContentBlock(ByVal nDBKey As Long) As ContentBlock
>        Dim oContentBlock As ContentBlock
>
>        For Each oContentBlock In Me.ContentBlocks
>            If oContentBlock.DBKey = nDBKey Then
>                Return oContentBlock
>            End If
>        Next
>        Return Nothing
>    End Function
>
> I always get this error at the "For Each..." line:
> "Unable to cast object of type 'System.Collections.DictionaryEntry' to
> type 'ContentObjects.ContentBlock'."
>
> I am using VS 2005
> Why do I get this error? Is it not possible to use for...each...next with
> custom collections based on DictionaryBase?
>
> Martin
>
>
Author
24 Jan 2006 12:39 PM
Martin Widmer
Hello

"Ken Tucker [MVP]" <vb***@bellsouth.net> schrieb im Newsbeitrag
news:uKysKRNIGHA.3752@TK2MSFTNGP11.phx.gbl...
> Hi,
>
>            The hash table inherits from dictionary base.  Each item is
> stored with its key in an dictonary entry.
>
>       Dim de As DictionaryEntry
>        For Each de In ht
>            Trace.WriteLine(de.Value)
>        Next

Thanks... I thought I RTFM but obviously not throroughly enough.

Martin
Author
24 Jan 2006 5:14 PM
Jay B. Harlow [MVP - Outlook]
Martin
| I am using VS 2005
Instead of using DictionaryBase consider using its "replacement":

System.Collections.ObjectModel.KeyedCollection(Of TKey, TItem)
http://msdn2.microsoft.com/ms132438(en-US,VS.80).aspx

Something like:

Public Class ContentBlocksCollection
    Inherits System.Collections.ObjectModel.KeyedCollection(Of Long,
ContentBlocks)

    Protected Overrides Function GetKeyForItem(ByVal item As ContentBlocks)
As Integer
        return item.DBKey
    End Function

    ' NOTE: Add, Remove, Contains handed to you via KeyedCollection!

End Class

My concern with the above is that ContentBlocksCollection.Item(Integer)
returns an item by index(ordinal position in collection), while
ContentBlocksCollection.Item(Long) returns an item by DBKey.

BTW: You do realize that Long is a 64-bit value, while Integer is a 32-bit
value?


A good replacement for CollectionBase is:

System.Collections.ObjectModel.Collection(Of T)
http://msdn2.microsoft.com/ms132397(en-US,VS.80).aspx


There are other collections in System.Collections.Generic that may be
beneficial.

--
Hope this helps
Jay [MVP - Outlook]
..NET Application Architect, Enthusiast, & Evangelist
T.S. Bradley - http://www.tsbradley.net


Show quoteHide quote
"Martin Widmer" <martin.wid***@businessnet.de> wrote in message
news:dr4on5$pe9$1@nntp.init7.net...
| Hi folks.
|
| I am using this collection class:
|
| Public Class ContentBlocksCollection
|    Inherits DictionaryBase
|    'Object variables for attributes
|    'Attributes
|    Default Public Property Item(ByVal nDBKey As Long) As ContentBlock
|        Get
|            Return MyBase.Dictionary.Item(nDBKey)
|        End Get
|        Set(ByVal value As ContentBlock)
|            MyBase.Dictionary.Item(nDBKey) = value
|        End Set
|    End Property
|    'Methods
|    Public Sub Add(ByVal oContentBlock As ContentBlock)
|        MyBase.Dictionary.Add(oContentBlock.DBKey, oContentBlock)
|    End Sub
|    Public Sub Remove(ByVal nDBKey As Long)
|        MyBase.Dictionary.Remove(nDBKey)
|    End Sub
|    Public Function Contains(ByVal nDBKey As Long) As Boolean
|        Return MyBase.Dictionary.Contains(nDBKey)
|    End Function
| End Class
|
| And now I want to iterate through it like this in the parent object
holding
| the collection:
|
|    'Methods
|    Public Function GetContentBlock(ByVal nDBKey As Long) As ContentBlock
|        Dim oContentBlock As ContentBlock
|
|        For Each oContentBlock In Me.ContentBlocks
|            If oContentBlock.DBKey = nDBKey Then
|                Return oContentBlock
|            End If
|        Next
|        Return Nothing
|    End Function
|
| I always get this error at the "For Each..." line:
| "Unable to cast object of type 'System.Collections.DictionaryEntry' to
type
| 'ContentObjects.ContentBlock'."
|
| I am using VS 2005
| Why do I get this error? Is it not possible to use for...each...next with
| custom collections based on DictionaryBase?
|
| Martin
|
|