На этот вопрос уже достаточно ответа, но для программистов, которые плохо знакомы с C # или с сериализацией, я думаю, что на самом деле очень полезно указать, что в общем случае исключения НЕ сериализуемы!
Это может звучать немного провокационно, но позвольте мне объяснить.
Это правда, что все исключения реализуют интерфейс ISerializable, но это только говорит о том, что он должен быть сериализуемым. Но реализация интерфейса НЕ делает объект сериализуемым (что в этом контексте подразумевает, что исключение может быть сериализовано и десериализовано).
Наиболее точный ответ на этот вопрос, как отмечали другие, заключается в том, что многие, но, безусловно, не все исключения в .Net Framework являются сериализуемыми. Но если вопрос использует термин «исключение .Net» в более широкой области, например, Исключение , полученное из System.Exception, тогда лучшим и более полезным ответом с точки зрения наилучшей практики и избежания ошибок является утверждение, которое я сделал выше, что в целом исключения не являются сериализуемыми.
И вот почему:
Как указывалось ранее, для того, чтобы Исключение было действительно Сериализуемым, у него должен быть правильный конструктор ctor(SerializationInfo, StreamingContext)
, и он должен быть украшен соответствующим атрибутом. Важно отметить, что ни одно из этих ограничений не вызывает ошибок компилятора, если они опущены!
Это означает, что класс NO , полученный из Exception, является сериализуемым, если не предприняты эти дополнительные, необязательные (с точки зрения компилятора) шаги.
т.е. любой неопытный / незнакомый кодер, который получает новое исключение, как показано ниже, только что создал исключение, которое НЕ Сериализуемо.
class MyNewException : Exception { }
Visual studio имеет отличный фрагмент «Exception», который позволяет довольно быстро генерировать новые сериализуемые исключения. Но даже в этом случае нечего напоминать или помогать программисту фактически сериализировать свойства объекта. Например, даже если приведенный ниже класс имеет соответствующий конструктор и атрибут, свойство MyNewField
не будет сериализовано без дополнительного кода как в конструкторе, так и в GetObjectData.
class MyNewException : Exception
{
public MyNewField { get; set; }
}
Итак, основной момент здесь заключается в том, что если вы по какой-то причине должны полагаться на правильную сериализацию и десериализацию исключений, имейте в виду, что когда дело доходит до любого пользовательского кода или сборок, нет гарантии, что он будет работать. Кроме того, поскольку требуемый конструктор обычно защищен, вы не обязательно сможете легко проверить его наличие (без отражения).
В моих собственных проектах в некоторых моментах я создал исключение "Прокси", которое может хранить некоторую информацию (например, сообщения и т. Д.) Из исключений, которые сами по себе не сериализуются. Их можно использовать для сериализации некоторой информации или в качестве альтернативы для десериализации данных, записанных в исключении, которое не имеет соответствующего конструктора.