views:

2049

answers:

5

I been learning basics of generics and it looks like it can really improve the performance of the application. But, I am not able to see the generic equivalent of Hashtable. Please share some sample C# code for creating generic hashtable classes. I need this for a demo.

edit:Thanks for the answers.

+17  A: 

Dictionary<TKey, TValue>

Note that Dictionary is not a 100% drop in replacement for HashTable. There is a slight difference in the way they handle NULLs.

Joel Coehoorn
I think you missed 'not' out of that.
Jeff Yates
I did, thank you.
Joel Coehoorn
What is the slight difference?
rvarcher
Dictionary will throw an exception if you try to reference a key that doesn't exist. HashTable will just return null.
Joel Coehoorn
The reason is that with a Dictionary, null might be a valid value for that key and mean something different than if the key doesn't exist at all.
Joel Coehoorn
Actually, Joel, I think the reason is that the value might be a reference type, which -cannot- be null. In a Hashtable the value was always Object, so returning null was at least possible.
Joel Mueller
Er, value type, not reference type. Oops.
Joel Mueller
+2  A: 

The generic version of System.Collection.Hashtable is System.Collections.Generic.Dictionary<TKey, TValue>.

bdukes
when would I use one over the other?
johnny
Unless you are trying to maintain interoperability with .NET 1.x, there is no benefit to using the non-generic collections over the generic collections.
bdukes
See When to Use Generic Collections (http://msdn.microsoft.com/en-us/library/ms172181.aspx) on MSDN for the full explanation
bdukes
+26  A: 

The generic version of Hashtable class is System.Collections.Generic.Dictionary class.

Sample code:

Dictionary<int, string> numbers = new Dictionary<int, string>( );
   numbers.Add(1, "one");
   numbers.Add(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);
   }
Gulzar
edited to link the MSDN loband version.
Gulzar
Curious. Why does Microsoft call it a dictionary and others a hashtable? Hashtable always seemed mysterious to me until I read about dictionaries in generics.
johnny
+11  A: 

The generic version of a Hashtable is the Dictionary<TKey,TValue> class (link). Here is some sample code translated from using a Hashtable into the most direct equivalent of Dictionary (argument checking removed for sake of brevity)

public HashTable Create(int[] keys, string[] values) { 
  HashTable table = new HashTable();
  for ( int i = 0; i < keys.Length; i++ ) {
    table[keys[i]] = values[i];
  }
  return table;
}

public Dictionary<object,object> Create(int[] keys, string[] values) {
  Dictionary<object,object> map = Dictionary<object,object>();
  for ( int i = 0; i < keys.Length; i++) {
    map[keys[i]] = values[i];
  }
  return map;
}

That's a fairly direct translation. But the problem is that this does not actually take advantage of the type safe features of generics. The second function could be written as follows and be much more type safe and inccur no boxing overhead

public Dictionary<int,string> Create(int[] keys, string[] values) {
  Dictionary<int,string> map = Dictionary<int,string>();
  for ( int i = 0; i < keys.Length; i++) {
    map[keys[i]] = values[i];
  }
  return map;
}

Even better. Here's a completely generic version

public Dictionary<TKey,TValue> Create<TKey,TValue>(TKey[] keys, TValue[] values) {
  Dictionary<TKey,TValue> map = Dictionary<TKey,TValue>();
  for ( int i = 0; i < keys.Length; i++) {
    map[keys[i]] = values[i];
  }
  return map;
}

And one that is even further flexible (thanks Joel for pointing out I missed this)

public Dictionary<TKey,TValue> Create<TKey,TValue>(
    IEnumerable<TKey> keys, 
    IEnumerable<TValue> values) {

  Dictionary<TKey,TValue> map = Dictionary<TKey,TValue>();
  using ( IEnumerater<TKey> keyEnum = keys.GetEnumerator() ) {
    using ( IEnumerator<TValue> valueEnum = values.GetEnumerator()) {
      while (keyEnum.MoveNext() && valueEnum.MoveNext() ) { 
        map[keyEnum.Current] = valueEnum.Current;
      }
    }
  }
  return map;
}
JaredPar
The next step is to use IEnumerable<T> rather than T[] for the function parameters.
Joel Coehoorn
Yep. Adding that in just a sec
JaredPar
One can stack "using()" statements without indentation and curly braces. Makes multiple using's more readable
data_smith
A: 

Dictionary.

Joan Venge