72

我正在使用字典来查找我正在处理的程序。我通过字典运行了一堆键,我希望一些键没有值。我抓住KeyNotFoundException它发生的地方,并吸收它。所有其他异常将传播到顶部。这是处理这个问题的最好方法吗?或者我应该使用不同的查找?字典使用一个 int 作为它的键,一个自定义类作为它的值。

4

6 回答 6

139

改用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);
}
于 2009-03-03T14:42:52.480 回答
37

尝试使用:Dict.ContainsKey

编辑:
性能方面,我认为Dictionary.TryGetValue正如其他一些建议的那样更好,但我不喜欢在不需要时使用 Out,所以我认为 ContainsKey 更具可读性,但如果您还需要该值,则需要更多代码行。

于 2009-03-03T14:42:44.257 回答
33

使用的一条线解决方案TryGetValue

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

请注意,value变量必须是字典在这种情况下返回的类型string。这里不能使用var进行变量声明。

如果您使用的是 C# 7,在这种情况下,您可以包含var 并内联定义它:

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

这也是一个很好的扩展方法,它将完全按照您想要实现的 dict.GetOrDefault("Key") 或 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;
 }
于 2014-08-04T21:10:31.957 回答
16

这是一个单行解决方案(请记住,这会进行两次查找。请参阅下面的 tryGetValue 版本,它应该在长时间运行的循环中使用。)

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

然而,我发现自己每次访问字典时都必须这样做。我希望它返回 null 所以我可以写:

string value = dictionary[key] ?? "default";//this doesn't work
于 2013-07-02T22:50:30.960 回答
5

您应该使用 Dictionary 的 'ContainsKey(string key)' 方法来检查键是否存在。对正常程序流使用异常不被认为是一种好的做法。

于 2009-03-03T14:44:47.327 回答
5

我知道这是一个旧线程,但如果它有帮助,那么之前的答案很好,但是可以解决复杂性的评论和乱扔代码的担忧(所有这些对我也有效)。

我使用自定义扩展方法以更优雅的形式将上述答案的复杂性包装起来,这样它就不会在整个代码中乱七八糟,然后它可以很好地支持 null coalesce operator 。. . 同时也最大化性能(通过上面的答案)。

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";
于 2019-02-13T20:53:13.333 回答