Why is Dictionary preferred over Hashtable in C#?

For what it's worth, a Dictionary is (conceptually) a hash table.

If you meant "why do we use the Dictionary<TKey, TValue> class instead of the Hashtable class?", then it's an easy answer: Dictionary<TKey, TValue> is a generic type, Hashtable is not. That means you get type safety with Dictionary<TKey, TValue>, because you can't insert any random object into it, and you don't have to cast the values you take out.

Interestingly, the Dictionary<TKey, TValue> implementation in the .NET Framework is based on the Hashtable, as you can tell from this comment in its source code:

The generic Dictionary was copied from Hashtable's source

Source


Differences

Dictionary Hashtable
Generic Non-Generic
Needs own thread synchronization Offers thread safe version through Synchronized() method
Enumerated item: KeyValuePair Enumerated item: DictionaryEntry
Newer (> .NET 2.0) Older (since .NET 1.0)
is in System.Collections.Generic is in System.Collections
Request to non-existing key throws exception Request to non-existing key returns null
potentially a bit faster for value types bit slower (needs boxing/unboxing) for value types

Similarities:

  • Both are internally hashtables == fast access to many-item data according to key
  • Both need immutable and unique keys
  • Keys of both need own GetHashCode() method

Alternative .NET collections:

(candidates to use instead of Dictionary and Hashtable)

  • ConcurrentDictionary - thread safe (can be safely accessed from several threads concurrently)
  • HybridDictionary - optimized performance (for few items and also for many items)
  • OrderedDictionary - values can be accessed via int index (by order in which items were added)
  • SortedDictionary - items automatically sorted
  • StringDictionary - strongly typed and optimized for strings (now Deprecated in favor of Dictionary<string,string>)

Because Dictionary is a generic class ( Dictionary<TKey, TValue> ), so that accessing its content is type-safe (i.e. you do not need to cast from Object, as you do with a Hashtable).

Compare

var customers = new Dictionary<string, Customer>();
...
Customer customer = customers["Ali G"];

to

var customers = new Hashtable();
...
Customer customer = customers["Ali G"] as Customer;

However, Dictionary is implemented as hash table internally, so technically it works the same way.


FYI: In .NET, Hashtable is thread safe for use by multiple reader threads and a single writing thread, while in Dictionary public static members are thread safe, but any instance members are not guaranteed to be thread safe.

We had to change all our Dictionaries back to Hashtable because of this.


In .NET, the difference between Dictionary<,> and HashTable is primarily that the former is a generic type, so you get all the benefits of generics in terms of static type checking (and reduced boxing, but this isn't as big as people tend to think in terms of performance - there is a definite memory cost to boxing, though).