Best way to handle a KeyNotFoundException

C#ExceptionKeynotfoundexception

C# Problem Overview


I am using a dictionary to perform lookups for a program I am working on. I run a bunch of keys through the dictionary, and I expect some keys to not have a value. I catch the KeyNotFoundException right where it occurs, and absorb it. All other exceptions will propagate to the top. Is this the best way to handle this? Or should I use a different lookup? The dictionary uses an int as its key, and a custom class as its value.

C# Solutions


Solution 1 - C#

Use Dictionary.TryGetValue instead:

Dictionary<int,string> dictionary = new Dictionary<int,string>();
int key = 0;
dictionary[key] = "Yes";

string value;
if (dictionary.TryGetValue(key, out value))
{
    Console.WriteLine("Fetched value: {0}", value);
}
else
{
    Console.WriteLine("No such key: {0}", key);
}

Solution 2 - C#

Try using: Dict.ContainsKey

Edit:
Performance wise i think Dictionary.TryGetValue is better as some other suggested but i don't like to use Out when i don't have to so in my opinion ContainsKey is more readable but requires more lines of code if you need the value also.

Solution 3 - C#

One line solution using TryGetValue

string value = dictionary.TryGetValue(key, out value) ? value : "No key!";

Be aware that value variable must be of type which dictionary returns in this case string. Here you can not use var for variable declaration.

If you are using C# 7, in which case you CAN include the var and define it inline:

string value = dictionary.TryGetValue(key, out var tmp) ? tmp : "No key!";

Here is also nice extension method which will do exactly what you want to achieve dict.GetOrDefault("Key") or dict.GetOrDefault("Key", "No value")

public static TValue GetOrDefault<TKey, TValue>(this Dictionary<TKey, TValue> dictionary, TKey key, TValue defaultValue = default(TValue))
{
      if (dictionary != null && dictionary.ContainsKey(key))
      {
           return dictionary[key];
      }
      return defaultValue;
 }

Solution 4 - C#

Here is a one line solution (Keep in mind this makes the lookup twice. See below for the tryGetValue version of this which should be used in long-running loops.)

string value = dictionary.ContainsKey(key) ? dictionary[key] : "default";

Yet I find myself having to do this everytime I access a dictionary. I would prefer it return null so I can just write:

string value = dictionary[key] ?? "default";//this doesn't work

Solution 5 - C#

you should use the 'ContainsKey(string key)' method of the Dictionary to check if a key exists. using exceptions for normal program flow is not considered a good practice.

Solution 6 - C#

I know this is an old thread but in case it's helpful the prior answers are great, but the comments of complexity and concerns of littering the code (all valid for me also) can be addressed.

I use a custom extension method to wrap up the complexity of the above answers in a more elegant form so that it's not littered throughout the code, and it then enables great support for null coalesce operator . . . while also maximizing performance (via above answers).

namespace System.Collections.Generic.CustomExtensions
{
    public static class DictionaryCustomExtensions
    {
        public static TValue GetValueSafely<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key)
        {
            TValue value = default(TValue);
            dictionary.TryGetValue(key, out value);
            return value;
        }
    }
}

Then you can use it simply by importing the namespace System.Collections.Generic.CustomExtensions

string value = dictionary.GetValueSafely(key) ?? "default";

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionDan McClainView Question on Stackoverflow
Solution 1 - C#Jon SkeetView Answer on Stackoverflow
Solution 2 - C#PeterView Answer on Stackoverflow
Solution 3 - C#Jernej NovakView Answer on Stackoverflow
Solution 4 - C#MondayPaperView Answer on Stackoverflow
Solution 5 - C#Remco RosView Answer on Stackoverflow
Solution 6 - C#CajunCodingView Answer on Stackoverflow