RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX


Generic Dictionaries: Hidden Treasure of System.Collections.Generic

Generic dictionaries simplify common tasks, such as coordinating selection between a TreeView and a ListView—but their capabilities extend far beyond that, once you realize you can use DynamicInvoke() to execute delegates stored in the dictionary.

he Dictionary class in .NET 2.0's System.Colllections.Generic namespace provides the ability to create a strongly-typed dictionary where both the Keys and Values collections can accept any object-type. This capability enables novel solutions to typical programming problems—for example in coordinating the current selection where multiple controls represent the same data, such as synchronizing selection between a ListView and TreeView.

This article presents a few simple and practical examples of using generic dictionaries. It concludes with one "far-out" example (that could be used to implement late binding) and that I hope will get you excited about the power of these dictionaries and trigger creative ideas in your own work.

When you first encounter .NET 2.0's new generic facilities, you may assume, as I did, that these are some very neat tools for easily and flexibly creating strongly typed collections; for avoiding casting, boxing, and unboxing in collections or lists; and for ensuring type-safety in your code so that errors are flagged at compile time, rather than erupting at run-time.

What You Need
You need NET 2.0 to run the examples. I created them with Visual Studio 2005, but they should be easily replicable in any IDE that supports .NET 2.0, and has access to the standard TreeView and ListView controls.

The List and Collection objects in the Systems.Collections.Generic namespace give you all that functionality, and amplify your programming power by letting you create custom types using the generic type designator <T>. You can use the Comparer and Enumerator facilities to make custom generic types both enumerable and comparable.

More advanced structures such as Queue and Stack give you a head start on modeling typical data structures, and SortedDictionary gives you the tools for a Dictionary type with an inherent sort order.

What surprised and delighted me when I finally got around to looking at the capabilities of the generic Dictionary class was to find that it was much more flexible than I thought it would be. Having once programmed extensively in PostScript, which had similarly flexible dictionaries, this flexibility made me think of late-binding scenarios where, by either changing a value associated with a key, or changing the dictionary in which you looked up the key, you could manipulate semantic contexts. In fact a "dictionary stack" is, internally, how PostScript manipulates name-look-up and syntactic scoping; let me know if you find the party where you can bring that into the conversation!

Building a Generic Dictionary
To start, download and unzip the sample code, and open the GD_Example_1 project.

Open the code-behind Form1.cs file and check to make sure you see the declaration:

   using System.Collections.Generic;
Either in your head, or looking at the code, visualize/observe two controls on the form: a TreeView and a ListView. Each contains a set of 10 items. Now, add a generic dictionary declaration:

   private Dictionary nodeDictionary = 
      new Dictionary();
You now have a dictionary named nodeDictionary in which the Keys collection contains a set of TreeNode objects and the Values collection holds ListViewItems.

What (I hope) just came into your mind was all the times you may have manipulated the Tag property of control "inner-collection-objects" such as TreeNodes and ListViewItems so that when a user selected a TreeNode you could find and select a corresponding ListViewItem in the ListView—and vice-versa. You also probably remember that every time you accessed the Tag property, you had to cast the value to the proper object type (and casting, as we all know, is very expensive, and contributes to global warming). In other words, to get the corresponding ListViewItem stored in the Tag property of a TreeNode you had to write:

You probably remember using the Tag property to coordinate control selection, but until generics, you had to cast the value to the proper object type.
   ListViewItem currentListViewItem = (ListViewItem) 
Now you can use the nodeDictionary to look up a ListViewItem using a TreeNode as the key with no casting required:

   ListViewItem currentListViewItem =  
See the sidebar Getting Under the Hood of Generic Dictionaries for more information on the way generic dictionaries work.

Close Icon
Thanks for your registration, follow us on our social networks to keep up-to-date