And*_*eas 69 c# generics dictionary exception
有没有办法以一种影响所有泛型类的方式在C#中的以下异常中获取给定键的值?我认为这是微软的异常描述中的一个重大缺失.
"The given key was not present in the dictionary."
Run Code Online (Sandbox Code Playgroud)
更好的方法是:
"The given key '" + key.ToString() + "' was not present in the dictionary."
Run Code Online (Sandbox Code Playgroud)
解决方案可能涉及mixins或派生类.
Bra*_*NET 61
当您尝试索引不存在的内容时抛出此异常,例如:
Dictionary<String, String> test = new Dictionary<String,String>();
test.Add("Key1,"Value1");
string error = test["Key2"];
Run Code Online (Sandbox Code Playgroud)
很多时候,像物体这样的东西将成为关键,这无疑会让它变得更难.但是,您始终可以编写以下内容(或者甚至将其包装在扩展方法中):
if (test.ContainsKey(myKey))
return test[myKey];
else
throw new Exception(String.Format("Key {0} was not found", myKey));
Run Code Online (Sandbox Code Playgroud)
或更高效(感谢@ScottChamberlain)
T retValue;
if (test.TryGetValue(myKey, out retValue))
return retValue;
else
throw new Exception(String.Format("Key {0} was not found", myKey));
Run Code Online (Sandbox Code Playgroud)
微软选择不这样做,可能是因为它在大多数对象上使用时都没用.它很简单,可以自己做,所以只需滚动自己!
Sam*_*ell 16
在一般情况下,答案是否定的.
但是,您可以将调试器设置为在首次抛出异常时中断.此时,不存在的密钥将作为调用堆栈中的值访问.
在Visual Studio中,此选项位于:
Debug→Exceptions ...→公共语言运行时异常→System.Collections.Generic
在那里,你可以检查Thrown框.
对于在运行时需要信息的更具体的实例,只要您的代码使用IDictionary<TKey, TValue>
而不是直接绑定Dictionary<TKey, TValue>
,您就可以实现自己的字典类来提供此行为.
Ste*_*dis 13
如果有人在 2021 年仍然关心并有能力迁移到 .NET Core,.Net 5 终于告诉我们有问题的密钥的名称:
class Program
{
static void Main(string[] args)
{
Dictionary<string, object> dictionary = new()
{
["foo"] = new object()
};
Console.WriteLine(dictionary["bar"]);
}
}
Run Code Online (Sandbox Code Playgroud)
会给你:
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)
Run Code Online (Sandbox Code Playgroud)
.Net Framework 4.8 中的相同代码给出了旧的可怕消息。
至于那些无力迁移到 Core 的人,恐怕还没有真正可行的解决方案。用 替换所有索引器调用TryGetValue
是很麻烦的 - 更不用说是荒谬的。从 Dictionary 派生子类实际上是不可能的。是的,您可以声明一个new
索引器,但是多态性就会消失,因为只有在使用子类的引用时才会调用您的索引器。最后,创建自己的字典包装器可能是一个解决方案,但这又是一个不平凡的过程,特别是如果您想精确复制字典,它不仅实现而且IDictionary<TKey,TValue>
还实现:
System.Collections.Generic.IReadOnlyDictionary<TKey,TValue>
System.Collections.IDictionary
System.Runtime.Serialization.IDeserializationCallback
System.Runtime.Serialization.ISerializable
Run Code Online (Sandbox Code Playgroud)
对于异常消息来说,“仅仅”就有点过分了。
如果您想管理关键未命中,您应该使用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.");
}
Run Code Online (Sandbox Code Playgroud)