System.Exception.Data属性

Teo*_*gul 30 .net c# exception

System.Exception类(实际上是任何异常)都具有Data属性,该属性几乎总是为空的.抛出异常时,该字段是否有用?或者它有一些我不知道的内部用途?

Cod*_*ray 17

关于其使用的文件似乎很清楚(强调增加):

获取键/值对的集合,这些键/值对提供有关异常的其他用户定义信息.

为什么它首先存在?我认为这是Control一个Tag属性相同的原因.在.NET的早期阶段(在每个Bob和Betty程序员理解对象和继承之前),他们希望使API足够简单,以至于每个人都可以弄清楚如何向事物中添加额外的数据.

但是,创建派生自定义异常的重点System.Exception不一定是包含其他信息,而是使客户端可以将捕获的异常限制为只能处理的异常.如果他们知道如何处理代码可以抛出的一组已定义的异常,那么他们应该只能捕获这些异常,而不必捕获基System.Exception类.您绝对应该做的是要求客户端代码捕获非特定的异常类并读取属性以确定它是什么类型的异常(以及它们是否能够处理它).

我老实说以前从未使用过这个属性.我必须检查文档,甚至看到它确实存在.但我认为它对于实现自定义异常日志记录最有用.您可以将很多重要信息嵌入到Data属性中(无论异常类的派生级别如何),然后将其传递给您的日志记录代码.反射器表示它在少数几个地方内部用于此目的.您提供的所有信息都会自动为您正确序列化,这也很好.

  • 我使用Data属性来跟踪有关错误的其他信息 - 通常是发生错误的方法的状态信息,这样当我将错误传递给更高级别的处理程序时,所有状态信息都将包含在我的日志中.在追踪错误时,日志中的额外信息非常有用. (2认同)

Mla*_*vic 13

这里的另一个注意事项是,当我继承异常并添加属性时,我所做的是使属性实际上从数据字典中获取和设置,而不是从局部变量中获取和设置.

[Serializable]
public class PacketParseException : Exception
{
    public byte[] ByteData
    {
        get
        {
            return (byte[])this.Data["ByteData"];
        }
    }

    public PacketParseException(string message, byte[] data, Exception inner) : base(message, inner)
    {
        this.Data.Add("ByteData", data);
    }
}
Run Code Online (Sandbox Code Playgroud)

我看到它的方式,然后内部数据也可以从Exception中获得,例如在记录时,因此不需要转换为实际类型.


t3c*_*b0t 8

使用新版本CallerMemberNameAttribute,可以更轻松地使用该Data属性进行存储:

public class BetterException : Exception
{
    protected T GetValue<T>([CallerMemberNameAttribute] string propertyName = "")
    {
        return (T)Data[propertyName];
    }

    protected void SetValue<T>(T value, [CallerMemberNameAttribute] string propertyName = "")
    {
        Data[propertyName] = value;
    }
}
Run Code Online (Sandbox Code Playgroud)

用法:

class MyException : BetterException
{
    public MyException(string name)
    {
        Name = name;
    }

    public string Name
    {
        get { return GetValue<string>(); }
        set { SetValue(value); }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 这是一个奇妙的模式.我会更进一步,添加一个重写的ToString来自动包含数据属性. (3认同)