Why doesn't the dictionary have access to non-existent keys, like a hashtable?

If I use Hashtable , I can write code like this:

 object item = hashtable[key] ?? default_value; 

This works if key appears in the Hashtable .

I cannot do this with Dictionary<TKey. TValue> Dictionary<TKey. TValue> . If a key that is not in the dictionary will throw a KeyNotFoundException . So I need to write code like this:

 MyClass item; if (!(dict.TryGetValue(key, out item)) { item = default_value; } 

I wonder why this is so. Dictionary<TKey, TValue> is just a wrapper around the Hashtable . Why was this restriction added to it?

Edit:

For another point of view on PopCatalin's answer (see below), the code I wrote above will not work if the dictionary values ​​are of type value. If I use Dictionary<int, int> , then the code I would like to use is as follows:

 int i = dict[key] ?? default_value; 

And this will not compile because the dict[key] not a null or reference type.

+4
source share
6 answers

The difference between Dictionary<T> and a Hashtable is that Dictionary<T> is a generic type that can specialize in storing value types by reference types.

A hash table can only store reference types (a Object , passed by reference) and only value types that are placed in the field (also passed by reference).

When a dictionary specializes in value types, it must return these values ​​"by value" not by reference. Therefore, therefore, Dictionary<T> cannot return null because null is not a valid value for value types.

+7
source

There is one misconception in your post. A dictionary is not a wrapper around a hashtable. This is a completely different implementation.

The reason this change was made is basically justified by one statement: Null is a valid value for the hash table. Without this change, it is not possible to distinguish between a non-existing key and a value key with a null value using the access method []. A dictionary cleans it up.

+4
source

I wrote an extension for this.

 public static class DictionaryExtension { public static TValue GetValueOrDefault<TKey, TValue>(this Dictionary<TKey, TValue> items, string key) { if (items != null && items.ContainsKey(key)) { return items[key]; } return default(TValue); } } 
+2
source

If you look at the code using Reflector, you will see that the Dictionary is trying to find the key and will obviously throw an exception if it does not find the key.

 public TValue get_Item(TKey key) { int index = this.FindEntry(key); if (index >= 0) { return this.entries[index].value; } ThrowHelper.ThrowKeyNotFoundException(); return default(TValue); } 
+1
source

Dictionary.ContainsKey is probably better for you than TryGetValue.

But why, I have no idea.

+1
source

I am sure that this limitation is one of the functional reasons for creating a wrapper in the first place.

0
source

All Articles