Help writing a Generic Dictionary Collection
In vb.net 2003 I would probably write a dictionary Collection like this.
What is the proper way to write in vb.2005?
Do I need to implement the enumerator?
What extra function would be useful to add?
Can you help converting the below to a more generic type?
| |
'/ <summary> '/ A dictionary with keys of type String and values of type ClassDeclaration '/ </summary> Public Class CustomerCollection Inherits System.Collections.DictionaryBase Public Sub New() End Sub
Default Public Overridable ReadOnly Property Item(ByVal key As String) As Customer Get Return CType(Me.Dictionary(key), Customer End Get End Property Public Overridable Sub Add(ByVal value As Customer Me.Dictionary.Add(value.Name, value) End Sub 'Add Public Overridable Function Contains(ByVal key As String) As Boolean Return Me.Dictionary.Contains(key)
End Function Public Overridable Function ContainsKey(ByVal key As String) As Boolean Return Me.Dictionary.Contains(key)
End Function Public Overridable Function ContainsValue(ByVal value As Customer) As Boolean Return ContainsKey(value.Name) End Function Public Overridable Sub Remove(ByVal key As String) Me.Dictionary.Remove(key) End Sub Public Overridable ReadOnly Property Keys() As System.Collections.ICollection Get Return Me.Dictionary.Keys End Get End Property Public Overridable ReadOnly Property Values() As System.Collections.ICollection Get Return Me.Dictionary.Values End Get End Property End Class
|
My conversion so far is pretty poor and ridiculous.
| |
PublicMustInheritClass MyDictionaryBase(Of Tkey, Tvalue) Inherits Dictionary(Of Tkey, Tvalue)PublicSubNew() EndSub endsub
|
I wish they were more examples on generics!!!
Thanks a lot in advance
If you don't have any additional requirements, you may just as well go with the built-in Dictionary:
i.e.
| |
Dim myCollectionInstance As New System.Collections.Generic.Dictionary(Of String, Customer) |
No need to derive a new class. This is one place where generics really makes your day 
If you do want to add a method or two to your collection, but you know that it will always be use String:s as keys and Customer:s as values, you can do something like:
| | Public Class CustomerCollection Inherits System.Collections.Generic.Dictionary(Of String, Customer) <extra methods here>
End Class
|
Either way, you don't have to implement any enumerator - that is handled by the base class.
It is much more common (and a lot easier) to just consume the generic collections than to actually implement them. Could you please give us some more details as to what problem you are trying to solve here? (Or do you just want to explore the wonderful world of Generics
)
Best regards,
Johan Stenberg
Thanks a lot for your reply.
I think my main problem is that i Could not find enough information on generics and what actually they offer Obviosly i dont want to reinvent the wheel.
I am trying to build a collection of class collections that I could easily reuse and offer the base functionalities.
Is there a function to filter a collection?
EG I have a customer collection and I would like to pull all customers that comes from England?
I could not find an example how to filter or sort a dictionary or collectionBase class using generics. Could you help with an example
I also looked at "Power collections" .Why are they writing all that stuff if the generics collections that comes out of the box already do that?
This is my point I really dont know what the generics collections that MS introduced really do.I could not find a good explanation.
thanks a lot for answering
Oh, I'm not saying that there aren't some types of collections that are missing from the base framework, and where things like the "Power collections" will come in handy. One example of a collection type that I'm personally missing is a simple Set.
The ones that are included do provide a some of the most common types of collections, though.
There are four main considerations when implementing or choosing a collection; the set of functions that the collection offers, the performance characteristics for the functions based on the amount of data in the collection, how frequently you will call each function and the amount of memory that the collection will require.
Different collections may offer the same set of functions, but with very different performance characteristics...
I assume that you have found the documentation for the generic collections:
http://msdn2.microsoft.com/library/0sbxh9x2(en-us,vs.80).aspx
If one of the existing collections meets your needs, great, go ahead and use it. If not, you can sometimes combine the existing collections to get what you want (i.e. to get a sorted dictionary with a O(1) access time, you can use a sorted list to sort the keys, and use a "normal" dictionary to map keys to values - this will store the keys twice, but it will allow you to still use a hashtable to store the values).
To answer some of the specific questions:
To sort a dictionary, you can use the SortedDictionaryClass. This will keep your data sorted according to keys.
To filter a dictionary is slightly more complicated, because the semantics aren't as clear - what do you want to base your filter on? The key? The value? A combinarion of key and value? This you would probably have to implement yourself, but you can use the framework provided classes as a base.
To filter a List(Of G) or Array(Of G) you can use the Find/FindAll methods, where you can specify a Predicate<> to find all matching elements. See http://msdn2.microsoft.com/library/fh1w7y8z(en-us,vs.80).aspx for an example. To pull all Cusomers that come from England, you can do something like:
| | Imports System.Collections.GenericModule Module1 Public Class Customer Private _country As String Public Sub New(ByVal Country As String) _country = Country End Sub Public ReadOnly Property Country() As String Get Return _country End Get End Property End Class Public Class CountryFilter Private _country As String Public Sub New(ByVal Country As String) _country = Country End Sub Public Function Match(ByVal Item As Customer) As Boolean Return String.Equals(Item.Country, _country, StringComparison.CurrentCultureIgnoreCase) End Function End Class Sub Main() Dim myList As New List(Of Customer) myList.AddRange(New Customer() {New Customer("England"), New Customer("Sweden")}) Dim EnglandFinder As New CountryFilter("England") Dim englishCustomers As List(Of Customer) = myList.FindAll(AddressOf EnglandFinder.Match) End Sub End Module
|
This example allows you to specify additional countries to filter on. If you knew that you only needed to filter out English customers, you wouldn't have to use the CountryFilter class - the only reason that I added that was to hold the country to filter on...
There are also sort methods on List(Of G) and Array(Of G) that allow you to specify a Comparer(Of G) or a Comparison(Of G)
Best regards,
Johan Stenberg