KeyNotFoundException信息

use*_*662 5 c# silverlight

我有一个随机抛出" KeyNotFoundException" 的C#Silverlight应用程序.我不知道找不到什么钥匙.这引出了两个问题:

  1. 做了KeyNotFoundException存储/揭露什么键它试图找到?当我查看文档时,我没有看到任何暗示此信息可用的内容.
  2. 我在一般的Application.UnhandledException事件处理程序中捕获/记录此异常.我的问题是,如果我在这里捕获事件,我可以将ExceptionObject转换为KeyNotFoundException,并且如果它在#1中被询问,它仍然会获得关键信息吗?

非常感谢你的帮助!

dan*_*dan 5

当字典抛出a时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");   
    }  
}  
Run Code Online (Sandbox Code Playgroud)

更新/澄清

我实际上并没有打电话,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 
    });
Run Code Online (Sandbox Code Playgroud)

此外,我发现将特定键值放在异常消息中会使得很难在日志中聚合异常,具体取决于您使用的工具类型.(我正在使用一个通过外部异常消息对错误进行分组的方法).如果这会影响您,您可能希望将详细信息放在内部异常中:
throw new KeyNotFoundException( "key was not found", new KeyNotFoundException(serializedKey));


vcs*_*nes 4

AKeyNotFoundException是由于当键不存在时尝试使用给定键从字典中获取值而引起的。例如:

var dictionary = new Dictionary<string, string>();
var val = dictionary["mykey"];
Run Code Online (Sandbox Code Playgroud)

您可以查看所有使用词典的地方并自行确定。一般的最佳实践是,如果您要在字典中查找可能不存在的值,则使用TryGetValue. 每次捕获异常是一个更昂贵的操作,并且是不必要的:

string val;
if(dictionary.TryGetValue("mykey", out val))
{
     //The key was found. The value is in val.
}
else
{
    //The key was not present.
}
Run Code Online (Sandbox Code Playgroud)

您可以查看StackTrace它们的属性KeyNotFoundException来准确确定问题发生的位置。所有异常都具有该StackTrace属性,因此您无需关心全局错误处理程序中的异常类型。例如:

private void Application_UnhandledException(object sender, 
        ApplicationUnhandledExceptionEventArgs e)
    {
         var stackTrace = e.ExceptionObject.StackTrace;
         //Log the stackTrace somewhere.
    }
Run Code Online (Sandbox Code Playgroud)

或者,如果您想知道它是什么类型的异常:

private void Application_UnhandledException(object sender, 
        ApplicationUnhandledExceptionEventArgs e)
    {
         if (e.ExceptionObject is KeyNotFoundException)
         {
             //This was a KeyNotFoundException
         }
    }
Run Code Online (Sandbox Code Playgroud)