给定的键在词典中不存在。哪个键?


76

有没有一种方法可以影响所有通用类,从而在C#中的以下异常中获取给定键的值?我认为这是Microsoft的异常描述中的一个大小姐。

"The given key was not present in the dictionary."

更好的方法是:

"The given key '" + key.ToString() + "' was not present in the dictionary."

解决方案可能涉及mixin或派生类。


13
这个问题似乎是题外话,因为它是关于异常消息的实现的喧嚣,而不是编程问题。
2014年

6
这里的问题是调试器并非总是可用,例如在读取日志文件时。
2014年

4
您假设所有字典都有一个.ToString()有意义的键。对于a的情况,我同意Dictionary<string, *>这是对异常描述的不错补充,但不能将其应用于所有类型的Dictionary<*,*>对象。
demoncodemonkey

2
不会,但是即使key.ToString()有时会说“ Object”,它仍然可以在90%的情况下工作。
安德烈亚斯(Andreas)

3
我认为它不存在的一个原因是,MS绝对不知道密钥是什么或是否应该公开密钥。可能是PII或不应记录的秘密。比较安全的做法是,在您不知道谁去看的时候,公开较少的细节。
Mike Zboray 2014年

Answers:


70

当您尝试索引不存在的内容时,将引发此异常,例如:

Dictionary<String, String> test = new Dictionary<String,String>();
test.Add("Key1,"Value1");
string error = test["Key2"];

通常,像对象之类的东西通常是关键,这无疑使它变得更难获取。但是,您始终可以编写以下内容(甚至将其包装在扩展方法中):

if (test.ContainsKey(myKey))
   return test[myKey];
else
   throw new Exception(String.Format("Key {0} was not found", myKey));

或更有效(感谢@ScottChamberlain)

T retValue;
if (test.TryGetValue(myKey, out retValue))
    return retValue;
else
   throw new Exception(String.Format("Key {0} was not found", myKey));

Microsoft选择不执行此操作,可能是因为在大多数对象上使用时将无用。它很简单,可以自己做,所以只需自己动手!


18
ContainsKey那么索引将导致字典两个查找。进行aTryGetValue只是一次查找,您可以仅使用其布尔输出来选择if / else块。
Scott Chamberlain 2014年

1
@ScottChamberlain非常正确。作为附加实现添加。
BradleyDotNET

尝试返回一个布尔值的test.keys.contains(key)。
Kurkula 2015年

17

在一般情况下,答案是“否”。

但是,您可以将调试器设置为在首次引发异常的位置中断。届时,不存在的密钥将作为调用堆栈中的值进行访问。

在Visual Studio中,此选项位于:

调试→异常...→通用语言运行时异常→System.Collections.Generic

在这里,您可以选中“投掷”框。


对于在运行时需要信息的更特定的实例,只要您的代码使用IDictionary<TKey, TValue>并且不直接绑定到Dictionary<TKey, TValue>,则可以实现自己的提供此类行为的字典类。


这通常是我运行调试器的方式。
AaronLS 2014年

@Sam,您好,您在调用堆栈中的哪一点找到此值?
user919426

2
VS 2017(v15.5.7)具有:调试-> Windows->异常设置->然后检查System.Collections.Generic.KeyNotFoundException
Robert Koch,

9

如果要管理键丢失,则应使用TryGetValue

https://msdn.microsoft.com/zh-CN/library/bb347013(v=vs.110).aspx

string value = "";
if (openWith.TryGetValue("tif", out value))
{
    Console.WriteLine("For key = \"tif\", value = {0}.", value);
}
else
{
    Console.WriteLine("Key = \"tif\" is not found.");
}

1
假定不存在该密钥的预期用法。事实并非如此。在合理的情况下,这可能是一个例外。
2014年

1
string Value = dic.ContainsKey("Name") ? dic["Name"] : "Required Name"

使用此代码,我们将在'Value'中获取字符串数据。如果字典“ dic”中存在键“ Name”,则获取此值,否则返回“ Required Name”字符串。


2
尽管此代码可以回答问题,但提供有关此代码为何和/或如何回答问题的其他上下文,可以改善其长期价值。
adiga

0

您可以尝试此代码

Dictionary<string,string> AllFields = new Dictionary<string,string>();  
string value = (AllFields.TryGetValue(key, out index) ? AllFields[key] : null);

如果键不存在,则仅返回一个空值。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.