C#
  Home arrow C# arrow Generics, Dictionaries, and More
ASP Free Forums 
.NET  
ASP  
ASP Code  
ASP.NET  
ASP.NET Code  
BrainDump  
C#  
Code Examples  
Database  
Database Code  
IIS  
Microsoft Access  
MS SQL Server  
Silverlight  
Visual Basic.NET  
Windows Scripting  
Windows Security  
XML  
Mobile Linux 
App Generation ROI 
IBM® developerWorks 
ASP Web Hosting  
ASP.NET Web Hosting 
Windows Web Hosting
 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us Get Paid 
Request Media Kit
Contact Us 
Site Map 
Privacy Policy 
Support 
 USERNAME
 
 PASSWORD
 
 
  >>> SIGN UP!  
  Lost Password? 
C#

Generics, Dictionaries, and More
By: O'Reilly Media
  • Search For More Articles!
  • Disclaimer
  • Author Terms
  • Rating: 4 stars4 stars4 stars4 stars4 stars / 3
    2008-12-24

    Table of Contents:
  • Generics, Dictionaries, and More
  • 4.10 Using foreach with Generic Dictionary Types
  • 4.11 Constraining Type Arguments
  • 4.12 Initializing Generic Variables to Their Default Values

  • Rate this Article: Poor Best 
      ADD THIS ARTICLE TO:
      Del.ici.ous Digg
      Blink Simpy
      Google Spurl
      Y! MyWeb Furl
    Email Me Similar Content When Posted
    Add Developer Shed Article Feed To Your Site
    Email Article To Friend
    Print Version Of Article
    PDF Version Of Article
     
     
    ADVERTISEMENT


    Generics, Dictionaries, and More


    (Page 1 of 4 )

    In this conclusion to a three-part series on generics in C#, you'll learn how to replace hash table objects with their generic counterparts, how to handle constraining type arguments, and more. This article is excerpted from chapter four of the C# 3.0 Cookbook, Third Edition, written by Jay Hilyard and Stephen Teilhet (O'Reilly, 2008; ISBN: 059651610X). Copyright © 2008 O'Reilly Media, Inc. All rights reserved. Used with permission from the publisher. Available from booksellers or direct from O'Reilly Media.

    4.9 Replacing the Hashtable with Its Generic Counterpart

    Problem

    You want to enhance the performance of your application as well as make the code easier to work with by replacing all Hashtable objects with the generic version.

    Solution

    Replace all occurrences of the System.Collections.Hashtable class with the type-safe generic System.Collections.Generic.Dictionary class.

    Here is a simple example of using aSystem.Collections.Hashtableobject:

      public static void UseNonGenericHashtable()
      {
         Console.WriteLine("\r\nUseNonGenericHashtable");

         // Create and populate a Hashtable
         Hashtable numbers = new Hashtable()
             { {1, "one"},"one"}, // Causes a boxing operation to occur for the key
               {2, "two"} }; // Causes a boxing operation to occur for the key

         // Display all key/value pairs in the Hashtable
         // Causes an unboxing operation to occur on each iteration for the key
         foreach (DictionaryEntry de in numbers)
         {
           
    Console.WriteLine("Key: " + de.Key + "\tValue: " + de.Value);
         }

         Console.WriteLine(numbers.IsReadOnly);
         Console.WriteLine(numbers.IsFixedSize);
         Console.WriteLine(numbers.IsSynchronized);
         Console.WriteLine(numbers.SyncRoot);

         numbers.Clear();
      }

    Here is that same code using aSystem.Collections.Generic.Dictionary<T,U>object:

      public static void UseGenericDictionary()
      {
         Console.WriteLine("\r\nUseGenericDictionary");

         // Create and populate a Dictionary
         Dictionary<int, string> numbers = new Dictionary<int, string>()
             { { 1, "one" }, { 2, "two" } };

         // Display all key/value pairs in the Dictionary
         foreach (KeyValuePair<int, string> kvp in numbers)
         {
           
    Console.WriteLine("Key: " + kvp.Key + "\tValue: " + kvp.Value);
         }

         Console.WriteLine(((IDictionary)numbers).IsReadOnly);
         Console.WriteLine(((IDictionary)numbers).IsFixedSize);
         Console.WriteLine(((IDictionary)numbers).IsSynchronized);
         Console.WriteLine(((IDictionary)numbers).SyncRoot);

         numbers.Clear();
      }

    Discussion

    For simple implementations of the Hashtable in your application, this substitution should be quite easy. However, there are some things to watch out for. For example, the generic Dictionary class does not implement the ICloneable interface, while the Hashtable class does.

    Table 4-3 shows the equivalent members that are implemented in both classes.

    Table 4-3. Equivalent members in the Hashtable and the generic Dictionary classes

    Members in the Hashtable class Equivalent members in the generic Dictionary class
    N/A Comparerproperty
    Countproperty Countproperty
    IsFixedSizeproperty ((IDictionary)myDict).IsFixedSize
    IsReadOnlyproperty ((IDictionary)myDict).IsReadOnly
    IsSynchronizedproperty ((IDictionary)myDict).IsSynchronized
    Itemproperty Itemproperty
    Keysproperty Keysproperty
    SyncRootproperty ((IDictionary)myDict).SyncRoot
    Valuesproperty Valuesproperty
    Addmethod Addmethod
    Clearmethod Clearmethod
    Clonemethod Use overloaded constructor, which accepts anIDictionarytype
    Containsmethod ContainsKeymethod
    ContainsKeymethod ContainsKeymethod
    ContainsValuemethod ContainsValuemethod
    CopyTomethod ((ICollection)myDict).CopyTo(arr,0)
    Removemethod Removemethod
    Synchronizedstatic method lock(myDictionary.SyncRoot) {...}
    N/A TryGetValuemethod

    In several cases within Table 4-3, there is not a one-to-one correlation between the members of aHashtableand the members of the genericDictionaryclass. Starting with the properties, notice that only theCount,Keys,Values, andItemproperties are present in both classes. To make up for the missing properties in theDictionaryclass, you can perform a cast to anIDictionary. The following code shows how to use these casts to get at the missing properties:

      Dictionary<int, string> numbers = new Dictionary<int, string>();

      Console.WriteLine(((IDictionary)numbers).IsReadOnly);
      Console.WriteLine(((IDictionary)numbers).IsFixedSize);
      Console.WriteLine(((IDictionary)numbers).IsSynchronized);
      Console.WriteLine(((IDictionary)numbers).SyncRoot);

    Note that due to the absence of code to be able to return a synchronized version of a genericDictionary, theIsSynchronizedproperty will always returnfalse. TheSyncRootproperty will always return the same object on which it is called. Essentially, this property returns thethispointer. Microsoft has decided to remove the ability to create a synchronous wrapper from any of the generic collection classes.

    Instead, they recommend using thelockkeyword to lock the entire collection or another type of synchronization object that suits your needs.

    Since theClonemethod is also missing from the genericDictionaryclass (due to the fact that this class does not implement theICloneableinterface), you can instead use the overloaded constructor, which accepts anIDictionary<T,U>type:

      // Create and populate a Dictionary
      Dictionary<int, string> numbers = new
      Dictionary<int, string>()
          { { 1, "one" }, { 2, "two" } };

      // Display all key/value pairs in the original Dictionary.
      foreach (KeyValuePair<int, string> kvp in numbers)
      {
        
    Console.WriteLine("Original Key: " + kvp.Key + "\tValue: " + kvp.Value);
      }

      // Clone the Dictionary object.
      Dictionary<int, string> clonedNumbers = new Dictionary<int, string>(numbers);

      // Display all key/value pairs in the cloned Dictionary.
      foreach (KeyValuePair<int, string> kvp in numbers)
      {
         Console.WriteLine("Cloned Key: " + kvp.Key + "\tValue: " + kvp.Value);
      }

    There are two more methods that are missing from theDictionaryclass, theContainsandCopyTo methods. TheContainsmethod is easy to reproduce in theDictionaryclass. In theHashtableclass, theContainsmethod and theContainsKey method both exhibit the same behavior; therefore, you can simply use theContainsKeymethod of theDictionaryclass to simulate theContains method of theHashtable class:

      // Create and populate a Dictionary
     
    Dictionary<int, string> numbers =
          new Dictionary<int, string>()
          { { 1, "one" }, { 2, "two" } };

      Console.WriteLine("numbers.ContainsKey(1) == " + numbers.ContainsKey(1));
      Console.WriteLine("numbers.ContainsKey(3) == " + numbers.ContainsKey(3));

    TheCopyTomethod is also easy to simulate in theDictionaryclass, but it involves a little more work:

      // Create and populate a Dictionary
     
    Dictionary<int, string> numbers =
          new Dictionary<int, string>()
          { { 1, "one" }, { 2, "two" } };

      // Display all key/value pairs in the Dictionary.
      foreach (KeyValuePair<int, string> kvp in numbers)
      {
        
    Console.WriteLine("Key: " + kvp.Key + "\tValue: " + kvp.Value);
      }
      // Create object array to hold copied information from Dictionary object.
      KeyValuePair<int, string>[] objs = new KeyValuePair<int, string>[numbers.Count];

      // Calling CopyTo on a Dictionary
      // Copies all KeyValuePair objects in Dictionary object to objs[]
      ((IDictionary)numbers).CopyTo(objs, 0);

      // Display all key/value pairs in the objs[].
      foreach (KeyValuePair<int, string> kvp in objs)
      {
        
    Console.WriteLine("Key: " + kvp.Key + "\tValue: " + kvp.Value);
      }

    CallingCopyToon theDictionaryobject involves setting up an array ofKeyValuePair<T,U>objects, which will end up holding all theKeyValuePair<T,U>objects within theDictionaryobject after theCopyTo method is called. Next, thenumbers Dictionaryobject is cast to anIDictionarytype so that theCopyTomethod may be called. Once theCopyTomethod is called, theobjsarray will contain copies of all theKeyValuePair<T,U>objects that are in the originalnumbersobject. Note that iteration of theobjsarray, using aforeachloop, is done in the same fashion as with thenumbersobject.

    See Also

    The “System.Collections.Hashtable Class” and “System.Collections.Generic.Dictionary Class” topics in the MSDN documentation.

    More C# Articles
    More By O'Reilly Media


       · This article is an excerpt from the book "C# 3.0 Cookbook, Third Edition," published...
     

    Buy this book now. This article is excerpted from chapter four of the C# 3.0 Cookbook, Third Edition, written by Jay Hilyard and Stephen Teilhet (O'Reilly, 2008; ISBN: 059651610X). Check it out today at your favorite bookstore. Buy this book now.

    C# ARTICLES

    - Coding a CRC-Generating Algorithm in C
    - Cyclic Redundancy Check
    - Handling Methods and Functions
    - Destroying Objects in C#
    - Creating Objects in C-Sharp
    - Classes and Objects
    - Programming Languages: Managed versus Native
    - LINQ-to-MySQL with DbLinq in C#
    - Working with Dates and Times in C#
    - Generics, Dictionaries, and More
    - More About Generics
    - Working with C# Collections
    - Generics
    - C# and XML
    - Pointers and Arrays in C#





    © 2003-2009 by Developer Shed. All rights reserved. DS Cluster 1 Hosted by Hostway
    For more Enterprise Application Development news, visit eWeek