我有一个随机抛出“KeyNotFoundException
”的C#Silverlight应用程序。我不知道找不到什么钥匙。这引出了两个问题:
KeyNotFoundException
是否存储/公开了它试图找到的密钥?当我查看documentation时,我没有看到任何暗示此信息可用的内容。非常感谢你的帮助!
答案 0 :(得分:5)
当字典抛出KeyNotFoundException
时,它不会试图告诉您它试图找到哪个键。因此,我通常尝试在我的字典上使用扩展方法,这样如果我的程序中断,我知道它尝试查找的键。虽然知道堆栈跟踪是有帮助的,但通常是不够的,特别是如果查找发生在循环内。
public static TValue GetOrThrow<TKey,TValue>(this IDictionary<TKey,TValue> d, TKey key)
{
try
{
return d[key];
}
catch(KeyNotFoundException ex)
{
throw new KeyNotFoundException(key.ToString()
+ " was not found in the dictionary");
}
}
更新/澄清
我实际上并没有调用key.ToString()
,因为它可能是一种不会覆盖ToString()
的类型。默认设置将打印类型名称:"MyLibrary.SomeType was not found."
,这不如"{ managerId: 123, employeeId: 456} was not found."
有用。
相反,我把它序列化为json,就像这样:
var serializedKey = Newtonsoft.Json.JsonConvert.SerializeObject(
key,
new JsonSerializerSettings
{
//make it easy for humans to read
Formatting = Formatting.Indented,
//don't break on loops...that would cause a new error that hides the KeyNotFound!
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
});
此外,我发现将特定键值放在异常消息中可能会使日志中的异常难以聚合,具体取决于您使用的工具类型。 (我正在使用一个通过外部异常的消息对错误进行分组的方法)。如果这会影响您,您可能希望将详细信息放在内部异常中:
throw new KeyNotFoundException(
"key was not found",
new KeyNotFoundException(serializedKey));
答案 1 :(得分:4)
KeyNotFoundException
是由于当键不存在时尝试使用给定键从字典中获取值。例如:
var dictionary = new Dictionary<string, string>();
var val = dictionary["mykey"];
您可以查看使用字典的所有地方并确定自己。一般的最佳实践是,如果您在字典中查找可能不存在的值,则使用TryGetValue
。每次捕获异常是一项更昂贵的操作,并且是不必要的:
string val;
if(dictionary.TryGetValue("mykey", out val))
{
//The key was found. The value is in val.
}
else
{
//The key was not present.
}
您可以查看他们StackTrace
的{{1}}属性,以确定问题的确切位置。所有异常都具有KeyNotFoundException
属性,因此您无需关心它在全局错误处理程序中的异常类型。例如:
StackTrace
或者,如果您想知道它是什么类型的异常:
private void Application_UnhandledException(object sender,
ApplicationUnhandledExceptionEventArgs e)
{
var stackTrace = e.ExceptionObject.StackTrace;
//Log the stackTrace somewhere.
}
答案 2 :(得分:3)
我认为找到问题的最佳方法是在Application.UnhandledException方法中记录给定异常的StackTrace。通过StackTrace,您可以找到问题的根源(方法的名称,导致异常的文件的名称和行)。这样,您就可以了解代码的错误。 总是尽可能多地记录。
答案 3 :(得分:0)
因为windows phone的silverlight不支持wsHttpBinding,所以你将服务改为basicHttpBinding并且它会起作用