C# 处理 KeyNotFoundException 的最佳方法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/606636/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 10:06:28  来源:igfitidea点击:

Best way to handle a KeyNotFoundException

c#exceptionkeynotfoundexception

提问by Dan McClain

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 KeyNotFoundExceptionright 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.

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

采纳答案by Jon Skeet

Use Dictionary.TryGetValueinstead:

使用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);
}

回答by Peter

Try using: Dict.ContainsKey

尝试使用:Dict.ContainsKey

Edit:
Performance wise i think Dictionary.TryGetValueis 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.

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

回答by Remco Ros

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.

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

回答by MondayPaper

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.)

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

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:

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

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

回答by Jernej Novak

One line solution using TryGetValue

使用一行解决方案 TryGetValue

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

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

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

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

如果您正在使用C#7,在这种情况下,你的CAN包括var和内联定义它:

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")

这也是很好的扩展方法,它可以完全满足您的要求 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;
 }

回答by CajunCoding

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

然后你可以简单地通过导入命名空间System.Collections.Generic.CustomExtensions来使用它

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