以下是我在C#中的代码:
catch(Exception ex)
{
ex.Data.Add("VarName", "object");
throw;
}
问题:如上所述,我是否会丢失我要添加到数据字典中的条目? - >在我看来,我正在重新抛出catch语句中捕获的异常,并且它还没有从下一行添加的Dictionary记录。
上面的代码应该是:
catch(Exception ex)
{
ex.Data.Add("VarName", "object");
throw ex;
}
在网上和SO上搜索过这个,但没有运气。
TIA!
答案 0 :(得分:3)
您的初始代码应该可以正常工作。你不应该丢失字典条目。
[编辑] :详细说明。
我们来看下面的示例代码:
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
时,真正引发的是对Exception对象的引用。该引用是被捕获和重新引发的内容。修改底层对象很好。这是您的初始代码所做的,以及我的示例中的Change
方法。
在Replace
方法中,我们不是修改对象,而是修改引用本身。我们将它指向一个全新的Exception
对象,其中包含不同的消息,最重要的是我们还添加了一些数据。但是,所有这些东西都丢失了,因为没有参数的throw
会重新抛出原始引用。
如果需要使用第二种情况,您可以通过将原始异常包含在InnerException
中来跟踪堆栈跟踪,就像我在Inner
方法中所做的那样。