2

以下是我在 C# 中的代码:

catch(Exception ex)
{
   ex.Data.Add("VarName", "object");
   throw;
}

问题:执行上述操作,我是否会丢失要添加到数据字典中的条目?--> 在我看来,我正在重新抛出 catch 语句中捕获的异常,并且它还没有从下一行添加的 Dictionary 记录。

上面的代码应该是:

catch(Exception ex)
{
   ex.Data.Add("VarName", "object");
   throw ex;
}
  • 但在这种情况下,我不想重置堆栈跟踪。

在网上和 SO 上搜索了这个,但没有运气。

蒂亚!

4

1 回答 1

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方法中所做的那样。

于 2013-08-20T15:46:25.430 回答