CollectionsUtil class ... usage?

M

Mark

I want to create a collection class that will be strongly typed (store a
specific object type), be keyed with a case insensitive string, and be able
to access objects stored by index, or sequentially (in the order stored) via
"For Each".

I know I could code this from scratch - or derived from a number of
framework classes, but I'm not sure of the pros/cons of various
possibilities.

I'd like to use some of the new Generics - they are sweet, but there is no
generic collection - they have dictionaries, lists, sorted list, etc.

Perhaps I can add a HashTable to a basic (derived) collection class.

But now I see this CollectionsUtil class, which has a
CreateCaseInsensitiveHashtable method. The docs on it are a bit sparse, no
usage examples. Can this be used with existing collection or dictionary
classes? If I had to, I could give up the indexed access requirement - and I
guess all of the collection classes provide enumerators so For Each and
foreach can be used (although with dictionaries, you are iterating over
DictionaryEntry items, not the stored objects).

I'd appreciate any advice/comments.

Thanks
 
K

Kevin Spencer

You're looking in the wrong Namespace. Look in
System.Collections.ObjectModel. The Collection<T> class sounds like just
what you need.

--
HTH,

Kevin Spencer
Microsoft MVP
Professional Numbskull

Hard work is a medication for which
there is no placebo.
 
V

V

Hi Mark,

As I understand it:
1. Typed Collection - Generics allows you to do this.
2. Keyed Collection - It has to be some kind of dictionary, i think the
Hashtable is a good example.
3. Case Insensitive - A custom implementation with an internal use of
the hashtable (to handle the case-insensitive key part) or even a
derived one.
4. Enumerable by index - Maybe use a SortedList flavor instead of a
hashtable (slower though). - Or maybe again customize the hashtable to
suit your needs.

I mean, why implement something of your own, when you can twist and
bend what is provided.

Regards,
Vaibhav
www.nagarro.com
 
C

Chris Dunaway

Use the Generic Dictionary class:

Dictionary<string, MyObjectType> myList = new Dictionary<string,
MyObjectType>();

If you need a case insensitive key, you need to create a class that
implements the IEqualityComparer interface. This class will have an
Equals method that returns true if two keys are equal.

Then you can create a generic Dictionary to use it:

Dictionary<string, MyObjectType> myList = new
Dictionary<string,MyObjectType>(new MyEqualityComparerClass());
 
M

Mark

Hey everyone,

Thanks for your thoughts. I did some experimenting and found that Kevin was
pretty much on the mark.

I tried a bunch of approaches just to see what would work well. My
requirements were that the class have the following features:
- a strongly typed (homogenous) collection - my test used a class named
Parameter
- an arbitrary string key that is associated with each object added to the
collection
- the key must be case insensitive (wound up making this optional)
- must be able to iterate of objects in collection
- must be able to access objects by index or key
- the order of objects in the collection must match the order in which they
were added (excepting insertions)

Methods/properties (all params are ByVal)
New 'parameterless constructor, yields case insensitive keys
New(ByVal CaseSensitiveKeys As Boolean) 'caller specifies case
sensitivity of keys
Add(Key As String, Item As Parameter)
Clear
Contains(Key As String)
Contains(Item As Parameter)
Count
IndexOf(Key As String)
IndexOf(Item As Parameter)
Insert(Key As String, Item As Parameter, Index As Integer)
Default ReadOnly Property Item(Key As String)
Default ReadOnly Property Item(Index As Integer)
Remove(Key As String)
Remove(Item As Parameter)
RemoveAt(Index As Integer)


1) Kevin's suggestion is probably the most workable, and cool because it
uses generics :) I used the Shadows keyword with the Add, Clear, Insert,
Remove and RemoveAt methods so I could prevent usage of these methods in the
base class, and allow my derived class to accept Key args and manage the
hash table.
Inherits Collections.ObjectModel.Collection(Of Parameter)

With private members:
Private m_oHash As Hashtable
Private m_bCaseInsensitive As Boolean


and use of CollectionsUtil.CreateCaseInsensitiveHashtable

This approach involved the least amount of code (about 85 lines)

2) a close second is the "standard" approach of implementing a strongly
typed collection, available since v1 of the framework:
Inherits System.Collections.CollectionBase

Private m_oHash As Hashtable
Private m_bCaseInsensitive As Boolean = True

This is very similar to the first option, except that one has to implement
the OnInsert, OnSet and OnValidate overrides, to insure that only objects of
the proper type are added to the collection. and we had to cast returns to
the proper type. Here, we only had to use Shadows for Clear and RemoveAt.

3) This looked great on paper:
Inherits System.Collections.Specialized.NameObjectCollectionBase

This class was meant to do almost exactly what I wanted, except only with
case sensitive keys. I worked around that limitation by lowering the case of
all passed Key parameters where case insensitive keys were selected.

This worked well, and was actually the shortest and cleanest implementation,
except that class' Enumerator would only allow iteration over the keys, not
the objects, so I discarded this after considering, but deciding not to,
rectify this limitation with a custom enumerator (I was running out of
experimentation time - have to get some work done at some point ;-)

4) Another option was simply a custom wrapper class around a HashTable
object
Implements IEnumerable

Private m_oHash As Hashtable
Private m_bCaseInsensitive As Boolean = True

This actually worked pretty well, and it obviously required no use of
Shadows, but it suffered the same fate as #3, a hash table is essentially a
dictionary, and its enumerator iterates over dictionary entries, not the
objects.

Thanks again for the feedback.

Cheers ...
 

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