2009-07-01 1 views
1

Ответ на What is the correct way to make exceptions serializable? говорит, что «правильная» базовая реализация для пользовательского исключения включает в себя 4 ctors:re: дизайн пользовательских исключений: должен ли я реализовать конструктор по умолчанию? конструктор «внутреннего исключения»?

[Serializable] 
public class SerializableExceptionWithoutCustomProperties : Exception 
{ 
    public SerializableExceptionWithoutCustomProperties() 
    { 
    } 

    public SerializableExceptionWithoutCustomProperties(string message) 
     : base(message) 
    { 
    } 

    public SerializableExceptionWithoutCustomProperties(string message, Exception innerException) 
     : base(message, innerException) 
    { 
    } 

    // Without this constructor, deserialization will fail 
    protected SerializableExceptionWithoutCustomProperties(SerializationInfo info, StreamingContext context) 
     : base(info, context) 
    { 
    } 
} 

Сразу, я бы сказал, что это действительно плохое имя для типа Exception. Но, кроме того,

  1. Для целей бинарной сериализации, что и С.О. вопрос имел в виду, я должен реализовать все 4 конструкторами? Я думаю, для целей [Serializable] я должен предоставить ctor, который принимает 2 аргумента типа (SerializationInfo, StreamingContext), потому что исключение происходит из System.Exception, которое само выполняет сериализацию. Я могу понять, что. Но должен ли я использовать другие ctors, , чтобы правильно обеспечить сериализуемое исключение? Я знаю, что если я хочу, чтобы тип был xml-сериализуемым, мне нужно предоставить стандартный (no-op) ctor. То же самое верно для [Serializable]? На мгновение остановимся на узкой заботе о [Serializable] и оставим в стороне все более широкие рекомендации относительно «каркасного дизайна».

  2. Переход к более широкому вопросу: The guidelines say что пользовательские исключения должны выполнять 4 общих ctors. Каковы причины этого руководства? Если я создаю настраиваемое исключение, действительно ли это плохие манеры или даже ошибка, если я не предоставляю null/default ctor? Это действительно плохие манеры или даже ошибка, если я не предоставляю ctor, который допускает внутреннее исключение? Зачем? Рассмотрим случай, когда мое настраиваемое исключение создается в моем коде библиотеки, и единственные экземпляры, которые я когда-либо бросал, включают сообщение и отсутствие внутреннего исключения.

  3. Короче говоря, является ли следующий код приемлемым для пользовательского исключения, которое не предоставляет дополнительных свойств?


[Serializable] 
public class CustomException : Exception 
{ 
    public CustomException(string message) : base(message) { } 

    // Without this constructor, deserialization will fail 
    protected CustomException(SerializationInfo info, StreamingContext context) 
     : base(info, context) { } 
} 

Смотри также: Winterdom blog: Make exceptions Serializable.

+0

Впервые я вижу, что кто-то использует «ctor» для обозначения конструктора O_o. К счастью для меня, вы использовали полное слово один раз, чтобы я мог понять название. Я предлагаю вам изменить свой заголовок ... – Ksempac

ответ

0

Мне не понравился ни один из ответов. Я соглашаюсь с моим предлагаемым решением, которое заключается в том, что я могу исключить «нормальные» конструкторы в моем настраиваемом исключении, включая конструктор по умолчанию и вложенный конструктор. Кроме того, мне нужно убедиться, что сериализация работает, из-за перекрестных вызовов.

0

Предложение: если другие будут использовать ваше исключение, а так как эти другие знакомы с исключениями .NET, то почему бы просто не следовать рекомендациям? Они те же, что используются .NET Framework.

Вы чувствуете, что это слишком много работы, учитывая количество настраиваемых типов исключений, которые вы определяете? Если это так, то это будет другой причиной для соблюдения рекомендаций, в которых указывается, что вы не должны создавать большое количество пользовательских исключений.

+0

Нет, не слишком много работы - конструкторы уже находятся в моем коде. Но мой код не использует половину из них, и я хотел бы рассмотреть возможность их удаления в рамках очистки кода. Эти исключения не предназначены для использования за пределами библиотеки, которую я предоставляю. Они брошены библиотекой, но я не ожидал, что какой-нибудь другой код их бросит. Является ли типичным, что я должен это допускать, поддерживайте это? – Cheeso

+0

Если они все для вашей библиотеки, сделайте их внутренними классами. Вы все равно должны реализовать все эти конструкторы и такие - вы или позже сопровождающие должны ожидать, что они будут «точно так же, как и любое другое исключение в .NET». –

+0

Мне интересно, в случае, когда пользовательское исключение включает дополнительные свойства, которые захватывают часть того, что происходило во время исключения, как мы можем заставить код, который бросает исключение, включать эти данные, если мы предоставляем конструкторы которые их не требуют? – bubbleking

2

Соответствующее предупреждение анализа кода является CA1032, а reference page обеспечивает это оправдание:

Неспособность обеспечить полный набор конструкторах может сделать это трудно правильно обрабатывать исключения. Для примера конструктор с подписями NewException (строка, Исключение) используется для создания исключений , вызванных другими исключениями .Без этого конструктора вы не можете создать и выбросить экземпляр своего пользовательского исключения, который содержит внутреннее (вложенное) исключение, , которым управляемый код должен делать в такой ситуации. Первые три конструктора исключений публикуются по соглашению . Четвертый конструктор защищен в незапечатанных классах и закрыт в закрытых классах.

Только вы или ваша команда проекта может решить, если ваша ситуация требует исключение (извините ...)

+0

ах, очень умный. Спасибо за выдержку. Это полезно. – Cheeso

1

Эй, я знаю, что это, по крайней мере рекомендована Microsoft. Если вы используете VS2008 (или возможно более ранние версии), вы можете легко позволить Visual Studio создать их для вас, набрав

exception 

в редакторе и нажать Tab (дважды?). Это создаст их, давая вам возможность дать классу новое имя.

Смежные вопросы