你的初始代碼應該工作得很好。你不應該丟失字典條目。
[編輯]:詳細說明。
讓我們以下面的例子代碼:
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