C#: переопределение метода ToString () для пользовательских исключений

StackOverflow https://stackoverflow.com/questions/1886611

  •  19-09-2019
  •  | 
  •  

Вопрос

У меня есть пользовательский класс исключений, который содержит некоторые дополнительные поля. Я хочу, чтобы они были записаны в ToString() метод, но если я внедрим свой собственный ToString(), Я теряю некоторые другие полезные вещи (например, написание имени типа исключения, данных внутренних исключений и трассировки стека).

Какой лучший способ/шаблон для реализации собственного ToString() метод для таких исключений? В идеале он должен повторно использовать существующий механизм, но быть отформатированным таким же, как и по умолчанию ToString() реализация.

Обновление: подготовка или добавление моих пользовательских полей в Base.toString () Текст не идеально, например, IMHO, например,

PimTool.Utilities.OERestServiceUnavailableException: test ---> System.InvalidOperationException: inner message
   --- End of inner exception stack trace ---
   at PimTool.Tests.Services.OE.OERestClientTests.ExceptionsLogging() in D:\svn\NewPimTool\PimTool.Tests\Services\OE\OERestClientTests.cs:line 178, 
   StatusCode=0, message='test', requestId='535345'

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

Обновление 2: Я реализовал решение для этого, ищите свой собственный ответ ниже.

Это было полезно?

Решение 3

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

public static class ExceptionFormatterExtensions
{
    public static string ExceptionToString (
        this Exception ex, 
        Action<StringBuilder> customFieldsFormatterAction)
    {
        StringBuilder description = new StringBuilder();
        description.AppendFormat("{0}: {1}", ex.GetType().Name, ex.Message);

        if (customFieldsFormatterAction != null)
            customFieldsFormatterAction(description);

        if (ex.InnerException != null)
        {
            description.AppendFormat(" ---> {0}", ex.InnerException);
            description.AppendFormat(
                "{0}   --- End of inner exception stack trace ---{0}",
                Environment.NewLine);
        }

        description.Append(ex.StackTrace);

        return description.ToString();
    }
}

Теперь вы можете использовать этот метод в своих реализациях ToString () без дублирования кода форматирования:

    public override string ToString()
    {
        return this.ExceptionToString(
            description =>
            {
                description.AppendFormat(
                    ", HttpStatusCode={0}, RequestId='{1}'", 
                    httpStatusCode, 
                    RequestId);
            });
    }

Другие советы

Это все излишнее. Ваше исключение должно просто переопределить свойство сообщения.

public override String Message {
    get {  
        return base.Message + String.Format(", HttpStatusCode={0}, RequestId='{1}'", 
                    httpStatusCode, 
                    RequestId);
    }
}

Метод ToString по умолчанию для класса исключений в основном "ClassName: Message --> InnerException.ToString() StackTrace«Таким образом, переопределение сообщения ставит текст вашего сообщения именно там, где оно должно быть.

Вы можете вручную добавить данные по умолчанию в строку, возвращенную ToString, глядя на свойства исключения. Например, следующее будет моделировать данные, возвращаемые по умолчанию исключением ToString Метод (при условии, что нет внутренних исключений):

string.Format("{0}: {1}\r\n{2}", this.GetType().Name, this.Message, this.StackTrace);

Или вы можете просто добавить (или приготовить) данные, возвращаемые base.ToString к информации, которую вы хотите добавить.

Вы можете переопределить метод ToString (), чтобы включить свою собственную информацию, и при этом вызовать базовое исключение по умолчанию toString () как это:

public class MyException : Exception
{
    public string CustomField { get; set; }
    public override string ToString()
    {
        return CustomField + Environment.NewLine + base.ToString();
    }
}

Если вы в основном смотрите на них в отладчике, то вы можете использовать [DebuggerDisplay] атрибут, чтобы указать их форматирование, а не прикоснуться к существующему ToString метод

В противном случае просто перегрузка ToString И обязательно позвоните в версию базового класса base.ToString()

Внутри переоборудования base.tostring () и изменить полученную строку для ваших потребностей ...

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top