I’m tired of making strongly-typed collections

I use stongly-typed collections all the time for items that are going to be reused quite often.  I have recently gone on an adventure to educate myself of what collection are available in the .Net Framework and how they differ.  My current scenario had a need for a collection to store a pair of strings and retain the order with which I added them to the collection, and I need to be able to bind the collection directly to a list control.  A dataset would be an overkill.  Right away, I know I’m going to be dealing with a key-value pair.  This automatically rules out all the collections based on the IList interface:  ArrayList, StringCollection.  Since I need a key-value pair, I need a collection based on IDictionary:  Hashtable, HybridDictionary, ListDictionary, and SortedList.  Not too many to choose from, but I refuse to extend CollectionBase for this tiny task that is isolated to one user control!


I began to explore the differences between these four collections that are all bases on IDictionary and all stored the key-value pair in a DictionaryEntry object.  What is really important is the underlying data structure of the collection. 


The Hashtable is meant to offer better-than-linear performance on lookups.  The order of the items is not guaranteed, and, in fact, you can add some items, then immediately iterate through to print them out, and they will often be in a completely different order.  Ok, Hashtable is disqualified.


They HybridDictionary works well for my purposes. . . only if the number of items is no greater than 10.  This is because it’s “Hybrid”.  With 10 items or fewer it implements a ListDictionary under the hood (see next section).  As soon as you add the 11th entry, it switches to a Hashtable, and all ordering reliability goes out the window.


The ListDictionary meets the requirements.  It stores a key-value pair, and it retains the order in which I add the items.  It does this by implementing the linked list data structure internally.  According to the SDK, the ListDictionary has better performance than a Hashtable up to 10 items, and then Hashtable becomes faster.  The SDK also warns that the ListDictionary should not be used with many items where performance is an issue.


I also looked at the SortedList just to make my comparison complete.  The SortedList behaves like a Hashtable in that you can use a key to look up the value, but you can also use the index to find the value.  Internally it keeps two arrays sychronized:  one array for the keys and one for the values.  It sorts the entries when added, so the list is always sorted, hence the name.


When whidbey gets here, I won’t have to worry about strongly-typed collections anymore.  I’ll be able to declare them generically. . . or is that specifically? 🙂  I can’t wait! 


I love the SDK.  Especially since I don’t have access to Google and my other online resources, I have used the SDK documentation so much!  It is a wealth of knowledge that every .Net developer should reference.


To get back to the collections, I did look at the NameValueCollection, but it does not implement IDictionary.  Also, I was not able to bind it to the list control in the way I wanted.  If I juse specified the source and then hit the “DataBind()” key [:-)], it would bind the list with the key value for the text as well as value.  But I need to set the DataTextField and DataValueField.  With IDictionary-based collections, “Key” and “Value” work, but the NameValueCollection returns a single string, not a DictionaryEntry object, so this presents a problem in getting the value in a binding situation.  Sure, I could iterate through it and get the keys and values, but I’m just databinding, so I had to rule out this collection.


Finally, I chose the ListDictionary for my purposes.  Then I started thinking that is some cases, my key-value set could become large, so I can’t use the ListDictionary.  I might have to write one more strongly-typed collection.  But for now, I’ll use an ArrayList of DictionaryEntry objects.  How’s that for thinking outside the box?  The ArrayList will grow dynamically and keep my items in a specific order because of the IList interface, but I can bind the key and value because the object being stored is a DictionaryEntry object.  I think I’ll call it DictionaryList.  So one more time, I have to extend CollectionBase (it’s internal data structure is an ArrayList).  Normally I could extend the DictionaryBase class, but internally it uses a Hashtable which doesn’t guarantee order.  And I’m back to strongly-typed collections. . . but this one I’ll reuse over and over and over and over. 

public class DictionaryList : CollectionBase
{
public DictionaryEntry this[int index]
{
get{ return((DictionaryEntry)List[index]);}
set{ List[index] = value;}
}
public int Add(object key, object value)
{
DictionaryEntry entry = new DictionaryEntry(key, value);
return List.Add(entry);
}
//rest of class truncated.
}

Ahh, the answer to so many of my problems! Now it’s so simple to pop a few items in and then bind to a list control:


 

list.DataSource = myDictionaryList;
list.DataTextField = “Key”;
list.DataValueField = “Value”;
list.DataBind( );
list.SelectedValue = myValue;