Подтвердить что ты не робот

С# - Зачем использовать стандартные конструкторы исключений?

Из MSDN, предупреждение анализа кода CA1032:

Exception types must implement the following constructors: 
  • public NewException()
  • public NewException(string)
  • public NewException(string, Exception)
  • protected or private NewException(SerializationInfo, StreamingContext)
Я понимаю цель конструктора сериализации, но является ли обоснование "требованием" других? Почему я не должен просто определять, какие конструкторы имеют смысл для использования моего исключения? Что делать, если я никогда не хочу бросать MyException, не передавая сообщение - почему я должен определять конструктор без параметров? Что, если я хочу, чтобы MyException имел свойство int, и мне нужны только конструкторы, которые инициализируют это свойство?
4b9b3361

Ответ 1

У вас есть хорошие ответы. Я просто хочу добавить, что предоставление этих дополнительных конструкторов необязательно требует много кодирования. Поскольку они уже реализованы в базовом классе, вы можете просто позволить этому сделать работу:

public class MyCustomException : Exception
{
    public MyCustomException() : base() { }
    public MyCustomException(string message) : base(message) { }
    public MyCustomException(string message, Exception innerException) : base(message, innerException) { }
    // and so on...
}

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

Ответ 2

Это предупреждение, а не требование. Это в принципе принцип наименьшего удивления. Предоставление всех 4 облегчает людям, используемым для "обычных" исключений С#, чтобы использовать ваши. Если у вас есть веские основания игнорировать руководство, сделайте это. Но он сломает определенные сценарии использования и сделает ваш класс менее интуитивным.

Ответ 3

Реализация стандартных конструкторов исключений позволяет людям использовать ваше исключение стандартным, знакомым способом, который встроен во все существующие исключения .NET. Первые три могут быть необязательными, если по какой-то причине вы не хотите, чтобы один из них использовался (хотя почему бы вам не хотелось, чтобы я не мог понять.) Однако последний из них является конструктором десериализации, и если вы хотите ваше исключение будет поддерживаться в любой распределенной среде (.NET Remoting, ASP.NET Web Services, WCF и т.д.), тогда это очень важно.

Без конструктора десериализации и атрибута [Serializable] ваши исключения не будут работать в распределенной среде и могут вызвать другие проблемы. Учитывая это и аспект знакомства с хорошо известными разработчиками С#, лучше всего реализовать по крайней мере 4 стандартных конструктора исключений и пометить ваши исключения с помощью [Serializable].

Ответ 4

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

Тот, который принимает другой Exception, таков, что можно связать все исключения с помощью свойства InnerException.

Наконец, есть тот, который принимает строку сообщения, что помогает использовать исключения, разумно согласованные.

Ответ 5

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