InvalidCastException使用Exception.Data的Dictionary<string, string>

7
我有一个客户端/服务器套件,我正在尝试使用Exception.Data将自定义信息传递到另一个类(ExceptionError)中,并将其传递到MessageBox。以下catch处理当我尝试连接到服务器而没有实际启动服务器来侦听连接时的情况。这只是疏忽在那一部分,侦听连接不是真正的问题,但它向我展示了Exception.Data的问题。
catch (Exception e)
{
    e.Data["SourceFile"] = "Client.cs";
    e.Data["MethodName"] = "Send_CommandToServer";
    e.Data["ExceptionType"] = "Exception";
    object[] exceptionArgs = new object[8] { null, e.InnerException, 
                              e.Message, null, e.Source, e.StackTrace, 
                              e.TargetSite, e.Data };
    ExceptionError.Show(exceptionArgs);
}

以下是抛出InvalidCastException异常的ExceptionError类中的代码行:

Dictionary<string,string> data = (Dictionary<string, string>)exceptionArgs[7];
 // exceptionArgs[7] is Exception.Data

以下是我收到的实际错误信息:

无法将类型为 'System.Collections.ListDictionaryInternal' 的对象强制转换为类型 'System.Collections.Generic.Dictionary`2[System.String,System.String]'。

我找不到任何关于ListDictionaryInternal的信息,我所做的大多数谷歌搜索都指向System.Collections.Specialized.ListDictionary,它本身也会产生一些问题。 有人知道有关ListDictionaryInternal的任何信息吗?还是您可以帮助我将 e.Data 传递到我的 ExceptionError 类中吗?


异常信息非常清晰,不清楚的是我在谷歌上找不到关于ListDictionaryInternal的任何信息,而且我以前从未使用过IDictionary或Exception.Data,所以我只是向Stackoverflow社区寻求帮助。 - roadmaster
2个回答

14

基本上,Exception.Data 的值不是 Dictionary<string, string> 类型,所以当你将其强制转换为 Dictionary<string, string> 时,会出现此异常。

属性本身 只声明为 IDictionary 类型。你不应该假设它是 Dictionary<string, string>。你应该修复你的 ExceptionError 类,避免这种假设。文档表明键通常是字符串,但这并不保证 - 同样不能保证值是字符串。

你可以通过仅转换适当的条目来执行从 IDictionaryDictionary<string, string> 的“安全”转换:

var dictionary = original.Cast<DictionaryEntry>()
                         .Where(de => de.Key is string && de.Value is string)
                         .ToDictionary(de => (string) de.Key,
                                       de => (string) de.Value);

2

Exception.Data 被定义为 IDictionary(字典),需按照文档要求使用。不要将其存储为 object[](对象数组)。相反,应将类型信息保留并作为形式参数发送到 ExceptionError.Show


有没有什么理由不将它“塞”进一个object[]中?在这种情况下,对我来说并不重要,我可以改变它,只是想知道是否存在某些性能惩罚或其他问题? - roadmaster
原因是代码清晰度和可维护性。表达式(Dictionary<string, string>)exceptionArgs[7]并不是自解释的。它感觉像是一个不必要的黑客,因为我们可以添加另一个参数。我看不出有什么缺点。 - usr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接