Custom collections

R

rufus

Hi,

I have a custom collection class that inherits from HashTable. When I add a
new CustomObject to my CustomCollection I would like to ensure that it will
only accept objects of type CustomObject. How would I do this? Thanks in
advance.

Public Class CustomCollection
Inherits Hashtable
' default constructor
Public Sub New()
End Sub
End Class

' this is how I would add new objects
Dim customCollection As New CustomCollection
'Now, fill it with some custom objects
customCollection.Add(1, New CustomObject("the key", "the value"))
 
J

Jay B. Harlow [MVP - Outlook]

Rufus,
Rather then inherit from HashTable, inherit from DictionaryBase.

Public Class CustomObjectCollection
Inherits DictionaryBase

Public Sub Add(ByVal key As Integer, ByVal value As CustomObject)
Me.InnerHashtable.Add(key, value)
End Sub

Default Public ReadOnly Property Item(ByVal key As Integer) As
CustomObject
Get
Return DirectCast(Me.InnerHashtable.Item(key), CustomObject)
End Get
End Property

End Class

Then add other typesafe methods as needed.

There is also a CollectionBase that wraps an ArrayList.

Hope this helps
Jay
 
R

rufus

Just what I was after! Many thanks.


Jay B. Harlow said:
Rufus,
Rather then inherit from HashTable, inherit from DictionaryBase.

Public Class CustomObjectCollection
Inherits DictionaryBase

Public Sub Add(ByVal key As Integer, ByVal value As CustomObject)
Me.InnerHashtable.Add(key, value)
End Sub

Default Public ReadOnly Property Item(ByVal key As Integer) As
CustomObject
Get
Return DirectCast(Me.InnerHashtable.Item(key), CustomObject)
End Get
End Property

End Class

Then add other typesafe methods as needed.

There is also a CollectionBase that wraps an ArrayList.

Hope this helps
Jay
 
R

rufus

Just one question though...why this line:

Return DirectCast(Me.InnerHashtable.Item(key), CustomObject)

I would have thought that 'Me.InnerHashtable.Item(key)' would always be
type CustomObject
 
J

Jay B. Harlow [MVP - Outlook]

Rufus,
You are correct the object being returned by Me.InnerHashtable is actually a
CustomObject, however the return type of Me.InnerHashtable is Object. The
DirectCast is telling the compiler that even though the return type of
Me.InnerHashtable is Object, you know its really a CustomObject being
returned. If you managed to get an object other then CustomObject into
Me.InnerHashtable then the DirectCast would cause an InvalidCastException at
runtime.

Without the DirectCast you would get a compile error if you are using Option
Strict On. You are using Option Strict On! As Option Strict On causes a lot
of compile time errors that are easier to identify rather then runtime
errors that may be much harder to identify & fix. Or worse cause a runtime
error that your user sees...


I should mention DictionaryBase supports the IDictionary interface. It has a
number of overridable methods such as OnInsert, OnSet, and OnValidate. The
DictionaryBase.On* methods allow you to do you own thing, such as validate
the object type. Overriding the DictionaryBase.On* methods are important if
you use the IDictionary interface to manipulate the object. For example if
you try the following with my original code:

Dim collection As New CustomObjectCollection
Dim dictionary As IDictionary = collection

collection.Add(1, New CustomObject)
collection.Add(2, New CustomObject)

dictionary.Add("3", "Hello World")

For Each de As DictionaryEntry In collection
Dim key As Integer = DirectCast(de.Key, Integer)
Dim value As CustomObject = DirectCast(de.Value, CustomObject)
Debug.WriteLine(value, key.ToString)
Next

You will get an exception on the "Dim key As Integer = DirectCast(de.Key,
Integer)" line, as the key to the third item added is a String, although we
"defined" our collection as only supporting Integer, Custom Object pairs.
The "problem" with the above code is that the "dictionary.Add" line may be
many many lines removed from the For Each making it a very hard problem to
track down.

If you override the OnValidate routine as below, then try the above code
again, you will receive an ArgumentException on the "dictionary.Add" line,
showing exactly where the problem is.

Public Class CustomObjectCollection
Inherits DictionaryBase

Public Sub Add(ByVal key As Integer, ByVal value As CustomObject)
Me.InnerHashtable.Add(key, value)
End Sub

Default Public ReadOnly Property Item(ByVal key As Integer) As
CustomObject
Get
Return DirectCast(Me.InnerHashtable.Item(key), CustomObject)
End Get
End Property

Protected Overrides Sub OnValidate(ByVal key As Object, ByVal value
As Object)
If Not TypeOf key Is Integer Then Throw New
ArgumentException("Key must be type Integer", "key")
If Not TypeOf value Is CustomObject Then Throw New
ArgumentException("Value must be type CustomObject", "value")
End Sub

End Class

See the on-line help for DictionaryBase on when you would use the other
DictionaryBase.On* methods. Most of the time I do not override them, however
its good to know you can for when you need them.

Hope this helps
Jay
 

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