System.Exception.Data属性

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

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

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

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

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

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

另外需要注意的是,当我inheritanceexception并添加属性时,我所做的是使属性实际上从数据字典中获取和设置,而不是从局部变量中获取和设置。

 [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); } } 

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

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

 public class BetterException : Exception { protected T GetValue([CallerMemberNameAttribute] string propertyName = "") { return (T)Data[propertyName]; } protected void SetValue(T value, [CallerMemberNameAttribute] string propertyName = "") { Data[propertyName] = value; } } 

用法:

 class MyException : BetterException { public MyException(string name) { Name = name; } public string Name { get { return GetValue(); } set { SetValue(value); } } }