C#: переопределение метода ToString () для пользовательских исключений
Вопрос
У меня есть пользовательский класс исключений, который содержит некоторые дополнительные поля. Я хочу, чтобы они были записаны в 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 () и изменить полученную строку для ваших потребностей ...