【发布时间】:2009-03-03 14:41:38
【问题描述】:
我正在使用字典来查找我正在处理的程序。我通过字典运行了一堆键,我希望一些键没有值。我在它出现的地方抓住了KeyNotFoundException,并吸收了它。所有其他异常将传播到顶部。这是处理这个问题的最好方法吗?或者我应该使用不同的查找?字典使用 int 作为键,自定义类作为值。
【问题讨论】:
标签: c# exception keynotfoundexception
我正在使用字典来查找我正在处理的程序。我通过字典运行了一堆键,我希望一些键没有值。我在它出现的地方抓住了KeyNotFoundException,并吸收了它。所有其他异常将传播到顶部。这是处理这个问题的最好方法吗?或者我应该使用不同的查找?字典使用 int 作为键,自定义类作为值。
【问题讨论】:
标签: c# exception keynotfoundexception
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);
}
【讨论】:
string value 作为 TryGetValue 的一部分:if (dictionary.TryGetValue(key, out string value))
尝试使用: Dict.ContainsKey
编辑:
性能方面,我认为Dictionary.TryGetValue 比其他一些建议更好,但我不喜欢在不需要的时候使用 Out,所以我认为 ContainsKey 更具可读性,但如果您也需要该值,则需要更多代码行。
【讨论】:
out,除非你必须这样做?
int.TryParse 就是一个例子..
使用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;
}
【讨论】:
这是一个单行解决方案(请记住,这会进行两次查找。请参阅下面的 tryGetValue 版本,它应该在长时间运行的循环中使用。)
string value = dictionary.ContainsKey(key) ? dictionary[key] : "default";
但我发现自己每次访问字典时都必须这样做。我希望它返回 null,所以我可以写:
string value = dictionary[key] ?? "default";//this doesn't work
【讨论】:
dictionary.ContainsKey,另一次查找dictionary[key]。使用@JernejNovak 的答案以获得更好的性能。
string value = dictionary.ContainsKey(key) ? dictionary[key] : "default"; 比string value = dictionary.TryGetValue(key, out value) ? value : "No key!"; 更具可读性吗
您应该使用 Dictionary 的 'ContainsKey(string key)' 方法来检查键是否存在。 对正常的程序流使用异常不是一种好的做法。
【讨论】:
我知道这是一个旧线程,但如果它有帮助,之前的答案很好,但是可以解决复杂性和乱扔代码的问题(对我也有效)。
我使用自定义扩展方法以更优雅的形式将上述答案的复杂性包装起来,这样它就不会在整个代码中乱扔垃圾,然后它可以很好地支持 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";
【讨论】: