The System.Exception class (actually any exception) has Data property which is almost always empty. While throwing exceptions, should this field be of any use? Or does it have s
Another note here, what I do when I inherit an exception and add properties, is to make the properties actually get and set from the data dictionary, and not from local variables.
[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);
}
}
The way I see it, then the internal data is available from an Exception as well, for example when logging, so no need to cast to actual type.
The documentation seems clear enough as to its use (emphasis added):
Gets a collection of key/value pairs that provide additional user-defined information about the exception.
Why does it exist in the first place? I assume it's the same reason Control
has a Tag property. In the early days of .NET (before every Bob and Betty programmer understood objects and inheritance) they wanted to make the API simple enough that everyone could figure out how to add extra data to things.
However, the point of creating custom exceptions that derive from System.Exception
is not necessarily to include additional information, but to make it possible for the client to limit the exceptions they catch to only those that they can handle. If they know how to handle a set of defined exceptions that your code can throw, they should be able to only catch those exceptions, without having to catch the base System.Exception
class. What you should definitely never do is require the client code to catch a non-specific exception class and read a property to determine what type of exception it is (and thus whether or not they are able to handle it).
I've honestly never used this property before. I had to check the documentation to even see that it did indeed exist. But I imagine it's most useful for implementing custom exception logging. You can embed a lot of important information into the Data
property (regardless of the level of derivation of exception class), and then pass that off to your logging code. Reflector indicates that it's used internally in a handful of places for precisely that purpose. It's also nice that all the information you provide here gets correctly serialized for you automatically.
With the new CallerMemberNameAttribute
it's even easier to use the Data
property for storage:
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;
}
}
Usage:
class MyException : BetterException
{
public MyException(string name)
{
Name = name;
}
public string Name
{
get { return GetValue<string>(); }
set { SetValue(value); }
}
}