你的初始代码应该工作得很好。你不应该丢失字典条目。
[编辑]:详细说明。
让我们以下面的例子代码:
using System;
class Program
{
static void Main()
{
Change();
Replace();
Inner();
}
static void Change()
{
try {
try {
throw new Exception("This is a message");
} catch (Exception e) {
e.Data.Add("foo", "bar");
throw;
}
} catch (Exception e) {
System.Diagnostics.Trace.WriteLine(e.Message);
System.Diagnostics.Trace.WriteLine(e.Data["foo"]);
}
}
static void Replace()
{
try {
try {
throw new Exception("This is a message");
} catch (Exception e) {
e = new Exception("Different message", e);
e.Data.Add("foo", "bar");
throw;
}
} catch (Exception e) {
System.Diagnostics.Trace.WriteLine(e.Message);
System.Diagnostics.Trace.WriteLine(e.Data["foo"]);
}
}
static void Inner()
{
try {
try {
throw new Exception("This is a message");
} catch (Exception e) {
e.Data.Add("foo1", "bar1");
e = new Exception("Different message", e);
e.Data.Add("foo2", "bar2");
throw e;
}
} catch (Exception e) {
System.Diagnostics.Trace.WriteLine(e.Message);
System.Diagnostics.Trace.WriteLine(e.Data["foo2"]);
System.Diagnostics.Trace.WriteLine(e.InnerException.Message);
System.Diagnostics.Trace.WriteLine(e.InnerException.Data["foo1"]);
}
}
}
当抛出一个Exception
,什么是真正的抛出是一个异常对象的引用。这个引用是被捕获和重新生成的。修改底层对象是好的。这是你最初的代码所做的,以及我的例子中的Change
方法。
在Replace
方法中,我们不修改对象,而是修改引用本身。我们使用不同的消息指向一个全新的Exception
对象,并且将它关闭,我们也添加一些数据。但是,所有这些东西都会丢失,因为没有参数的throw
会重新引发原始引用。
如果需要使用第二种情况,可以通过将原始异常作为InnerException
来跟踪堆栈跟踪,就像我在Inner
方法中所做的那样。
如果你想添加一些数据到异常,然后用数据包装异常在更具体的异常,并抛出该特定的异常 –
你试过了;编写一些测试代码示例应该不会超过几分钟? –
刚刚尝试 - 巴特的答案是正确的。我最初的代码工作得很好。 – coder0h1t