代码之家  ›  专栏  ›  技术社区  ›  Dan McClain

处理KeyNotFoundException的最佳方法

  •  57
  • Dan McClain  · 技术社区  · 17 年前

    KeyNotFoundException 就在它发生的地方,吸收它。所有其他异常将传播到顶部。这是最好的处理方法吗?或者我应该使用不同的查找?字典使用int作为其键,使用自定义类作为其值。

    6 回复  |  直到 14 年前
        1
  •  137
  •   Avi Turner    11 年前

    使用 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);
    }
    
        2
  •  37
  •   Peter    10 年前

    编辑:
    从性能上看,我认为 Dictionary.TryGetValue 正如其他建议的那样更好,但我不喜欢在不需要时使用Out,因此我认为ContainsKey更具可读性,但如果还需要值,则需要更多的代码行。

        3
  •  33
  •   Jernej Novak John Wu    6 年前

    使用 TryGetValue

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

    注意 一串 . 这里你不能用 用于变量声明。

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

    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;
     }
    
        4
  •  16
  •   MondayPaper    8 年前

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

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

    然而,我发现自己每次查字典都要这么做。我希望它返回null,这样我就可以写:

    string value = dictionary[key] ?? "default";//this doesn't work
    
        5
  •  5
  •   Remco Ros    17 年前

    对正常程序流使用异常被认为不是一种好的做法。

        6
  •  5
  •   CajunCoding    7 年前

    我使用一个自定义扩展方法将上述答案的复杂性以一种更优雅的形式包装起来,这样就不会在整个代码中乱七八糟,然后它就支持空合并运算符。同时最大限度地提高性能(通过以上答案)。

    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";
    
    推荐文章