In some certain scenario it appeared to be useful for me to have a short-spoken, readable way to get null
instead of the KeyNotFoundException
while accessing dictionary value by key, when there is no such key in the dictionary.
The first thing that came into my mind was an extension method:
public static U GetValueByKeyOrNull<T, U>(this Dictionary<T, U> dict, T key) where U : class //it's acceptable for me to have this constraint { if (dict.ContainsKey(key)) return dict[key]; else //it could be default(U) to use without U class constraint //however, I didn't need this. return null; }
But it's not very short-spoken actually, when you write something like this:
string.Format("{0}:{1};{2}:{3}", dict.GetValueByKeyOrNull("key1"), dict.GetValueByKeyOrNull("key2"), dict.GetValueByKeyOrNull("key3"), dict.GetValueByKeyOrNull("key4"));
I'd say, it would be much better to havesomething close to base syntax: dict["key4"]
.
Then I came up with an idea to have a class with a private
dictionary field, which exposed the functionality I need:
public class MyDictionary<T, U> //here I may add any of interfaces, implemented //by dictionary itself to get an opportunity to, //say, use foreach, etc. and implement them // using the dictionary field. where U : class { private Dictionary<T, U> dict; public MyDictionary() { dict = new Dictionary<T, U>(); } public U this[T key] { get { if (dict.ContainsKey(key)) return dict[key]; else return null; } set { dict[key] = value; } } }
But it seems a little overhead to get the slight change in the basic behaviour.
One more workaround could be to define a Func
in the current context like this:
Func<string, string> GetDictValueByKeyOrNull = (key) => { if (dict.ContainsKey(key)) return dict[key]; else return null; };
so it could be utilized like GetDictValueByKeyOrNull("key1")
.
Could you, please, give me any more suggestions or help to choose a better one?
Dictionary will hash the key supplie to get the index , in case of null , hash function can not return a valid value that's why it does not support null in key.
We can fix this exception by using the TryGetValue method. Note that could use ContainsKey instead of TryGetValue. But we preserve the intention of the previous code here. Important We use if-statement when testing values in the Dictionary, because there is always a possibility that the key will not exist.
In the same way, cities is a Dictionary<string, string> type dictionary, so it can store string keys and string values. Dictionary cannot include duplicate or null keys, whereas values can be duplicated or null.
null cannot be used as key in a dictionary, because you need a hashcode of the key. And the key must be unique. So you could replace null with some magic value, but it still would crash if you have multiple rows where the key is null .
Here is my solution from my personal library, implemented as an extension method. I am only posting it because it is implemented from the dictionary interface and allows an optional default value to be passed in.
Implementation
public static TV GetValue<TK, TV>(this IDictionary<TK, TV> dict, TK key, TV defaultValue = default(TV)) { TV value; return dict.TryGetValue(key, out value) ? value : defaultValue; }
Usage
MyDictionary.GetValue("key1"); MyDictionary.GetValue("key2", -1); MyDictionary.GetValue("key3")?.SomeMethod();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With