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).