Свойство System.Exception.Data - PullRequest
29 голосов
/ 30 апреля 2011

Класс System.Exception (фактически любое исключение) имеет свойство Data, которое почти всегда пусто.При создании исключений, должно ли это поле быть полезным?Или это имеет какое-то внутреннее использование, о котором я не знаю?

Ответы [ 3 ]

16 голосов
/ 30 апреля 2011

Документация кажется достаточно ясной в отношении ее использования (выделение добавлено):

Получает коллекцию пар ключ / значение, которые предоставляют дополнительную пользовательскую информацию об исключении .

Почему он вообще существует? Я предполагаю, что это та же самая причина, по которой Control имеет Tag свойство . В первые дни .NET (прежде чем каждый программист Боб и Бетти понимали объекты и наследование) они хотели сделать API-интерфейс достаточно простым, чтобы каждый мог понять, как добавить дополнительные данные к вещам.

Однако смысл создания пользовательских исключений, вытекающих из System.Exception, не обязательно должен включать дополнительную информацию, но чтобы позволить клиенту ограничить перехватываемые им исключения только теми, которые они может справиться. Если они знают, как обрабатывать набор определенных исключений, которые может генерировать ваш код, они должны иметь возможность только перехватывать эти исключения, без необходимости отлавливать базовый класс System.Exception. Что вам определенно следует никогда делать, так это требовать, чтобы клиентский код перехватывал неспецифический класс исключений и считывал свойство, чтобы определить, какой это тип исключения (и, следовательно, могут ли они его обрабатывать) ,

Честно говоря, я никогда раньше не использовал это свойство. Я должен был проверить документацию, чтобы даже увидеть, что она действительно существует. Но я думаю, что это наиболее полезно для реализации пользовательских журналов исключений. Вы можете вставить много важной информации в свойство Data (независимо от уровня происхождения класса исключений), а затем передать ее в свой код регистрации. Отражатель указывает, что он используется внутри в нескольких местах именно для этой цели. Также приятно, что вся информация, которую вы здесь предоставляете, автоматически сериализуется для вас автоматически.

12 голосов
/ 31 мая 2013

Еще одно замечание, которое я делаю здесь, когда я наследую исключение и добавляю свойства, - это заставить свойства фактически получать и устанавливать из словаря данных, а не из локальных переменных.

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

СпособЯ вижу это, тогда внутренние данные также доступны из Исключения, например, при регистрации, поэтому нет необходимости приводить к фактическому типу.

8 голосов
/ 03 ноября 2015

С новым 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;
    }
}

Использование:

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

    public string Name
    {
        get { return GetValue<string>(); }
        set { SetValue(value); }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...