Лучший способ обработать KeyNotFoundException - PullRequest
58 голосов
/ 03 марта 2009

Я использую словарь для поиска программы, над которой я работаю. Я запускаю связку ключей через словарь и ожидаю, что некоторые ключи не будут иметь значения. Я ловлю KeyNotFoundException прямо там, где это происходит, и поглощаю его. Все остальные исключения будут распространяться наверх. Это лучший способ справиться с этим? Или я должен использовать другой поиск? Словарь использует int в качестве ключа и пользовательский класс в качестве значения.

Ответы [ 6 ]

104 голосов
/ 03 марта 2009

Используйте Dictionary.TryGetValue вместо:

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);
}
33 голосов
/ 03 марта 2009

Попробуйте использовать: Dict.ContainsKey

Edit:
С точки зрения производительности, я думаю, Dictionary.TryGetValue лучше, чем некоторые другие, но я не люблю использовать Out, когда мне это не нужно, так что, по моему мнению, ContainsKey более читабелен, но требует больше строк кода, если вам также нужно значение.

21 голосов
/ 05 августа 2014

Однолинейное решение с использованием TryGetValue

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

Помните, что переменная value должна иметь тип, который словарь возвращает в этом случае string Здесь вы не можете использовать var для объявления переменных.

Если вы используете C # 7, в этом случае вы МОЖЕТЕ включить переменную и определить ее в строке:

string value = dictionary.TryGetValue(key, out var tmp) ? tmp : "No key!";
15 голосов
/ 03 июля 2013

Вот решение в одну строку (Имейте в виду, что это делает поиск дважды. См. Ниже версию tryGetValue, которая должна использоваться в длительных циклах.)

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

И все же мне приходится делать это каждый раз, когда я получаю доступ к словарю. Я бы предпочел, чтобы он возвращал ноль, поэтому я могу просто написать:

string value = dictionary[key] ?? "default";//this doesn't work
5 голосов
/ 03 марта 2009

Вы должны использовать метод словаря ContainsKey (string key), чтобы проверить, существует ли ключ. использование исключений для нормального выполнения программы не считается хорошей практикой.

4 голосов
/ 13 февраля 2019

Я знаю, что это старая ветка, но в случае, если она полезна, предыдущие ответы хороши, но можно рассмотреть комментарии о сложности и проблемах с засорением кода (все это также актуально для меня).

Я использую пользовательский метод расширения, чтобы обернуть сложность вышеприведенных ответов в более элегантную форму, чтобы она не была засорена в коде, а затем обеспечивает отличную поддержку оператора null coalesce. , , и в то же время максимизировать производительность (через ответы выше).

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;
        }
    }
}

Затем вы можете использовать его, просто импортировав пространство имен System.Collections.Generic.CustomExtensions

string value = dictionary.GetValueSafely(key) ?? "default";
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...