字典中不存在给定的关键字.哪把钥匙
本文关键字:关键字 钥匙 不存在 字典 | 更新日期: 2023-09-27 18:25:55
有没有一种方法可以以影响所有泛型类的方式获得C#中以下异常中给定键的值?我认为这是微软异常描述中的一个重大遗漏。
字典中不存在给定的关键字。
更好的方法是:
给定的密钥"+钥匙ToString()+"字典中没有。
解决方案可能涉及混合或派生类。
当您试图索引到不存在的东西时,会引发此异常,例如:
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));
微软选择不这样做,可能是因为它在大多数对象上使用时都是无用的。自己动手很简单,所以自己动手吧!
在一般情况下,答案是否定的。
但是,您可以将调试器设置为在首次引发异常时中断。届时,不存在的键将作为调用堆栈中的值进行访问。
在Visual Studio中,此选项位于以下位置:
调试.rar;例外→公共语言运行时异常&rar;System.Collections.Generic
在那里,您可以选中抛出框。
对于运行时需要信息的更具体的实例,如果您的代码使用IDictionary<TKey, TValue>
而不直接绑定到Dictionary<TKey, TValue>
,则可以实现自己的字典类,该类提供这种行为。
如果有人在2021年仍然关心,并且能够负担得起迁移到.NET Core,则.NET 5最终告诉我们违规密钥的名称:
class Program
{
static void Main(string[] args)
{
Dictionary<string, object> dictionary = new()
{
["foo"] = new object()
};
Console.WriteLine(dictionary["bar"]);
}
}
会给你:
Unhandled exception. System.Collections.Generic.KeyNotFoundException: The given key 'bar' was not present in the dictionary.
at System.Collections.Generic.Dictionary`2.get_Item(TKey key)
at KnfTest.Program.Main(String[] args)
.Net Framework 4.8中的相同代码给出了旧的可怕消息。
至于那些还负担不起搬到Core的人,恐怕没有真正可行的解决方案。用TryGetValue
替换所有索引器调用是很麻烦的,更不用说荒谬了。从字典中划分子类实际上是不可能的。是的,您可以声明new
索引器,但多态性会消失,因为只有在使用子类的引用时才会调用索引器。最后,创建您自己的Dictionary包装器可能是一个解决方案,但这也是一个不平凡的过程,尤其是如果您想完全复制Dictionary,它不仅实现IDictionary<TKey,TValue>
,还实现
System.Collections.Generic.IReadOnlyDictionary<TKey,TValue>
System.Collections.IDictionary
System.Runtime.Serialization.IDeserializationCallback
System.Runtime.Serialization.ISerializable
真是小题大做"只是";以获取异常消息。
如果您想管理密钥未命中,您应该使用TryGetValue
https://msdn.microsoft.com/en-gb/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.");
}
string Value = dic.ContainsKey("Name") ? dic["Name"] : "Required Name"
使用此代码,我们将获得"Value"中的字符串数据。如果关键字"Name"存在于字典"dic"中,则获取此值,否则返回"Required Name"字符串。
您可以尝试此代码
Dictionary<string,string> AllFields = new Dictionary<string,string>();
string value = (AllFields.TryGetValue(key, out index) ? AllFields[key] : null);
如果密钥不存在,它只返回一个null值。
从@BradleyDotNET的anwser借用,这是扩展方法版本:
public static TValue GetValue<TKey, TValue>(this Dictionary<TKey, TValue> dictionary, TKey key)
{
if (dictionary.TryGetValue(key, out TValue result))
{
return result;
}
else
{
throw new KeyNotFoundException($"The given key '{key}' was not present in the dictionary.");
}
}
在C#7.0或更高版本中,您可以使用out参数修饰符在一行中解决问题,并且只对索引器进行一次调用。它适用于c#7.0或更高版本。
public TItem GetOrException<TKey,TItem>(TKey key) where TKey : IFormattable =>
dictionary.TryGetValue(key, out var item) ? item : throw new KeyNotFoundException( "Key: " + key.ToString() );
您也可以选择更长的try-catch块,它可以提供更好的异常信息:
public TItem GetOrException<TKey,TItem>(TKey key) where TKey : IFormattable {
try{ return dictionary[key]; }
catch (KeyNotFoundException e) { throw new KeyNotFoundException("Key:" + key.ToString(), e);}
}