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

M

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
 
A

Armin Zingler

Martin Widmer said:
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
 
K

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
 
M

Martin Widmer

Hello

Ken Tucker said:
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
 
J

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


| 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
|
|
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top