Почему классы, не помеченные как Serializable, нельзя сериализовать с помощью BinaryFormatter?

Как мы все знаем и упоминали на сайте MSDN:

Архитектура сериализации, поставляемая с .NET Framework, автоматически правильно обрабатывает графы объектов и циклические ссылки. Единственное требование, предъявляемое к графам объектов, - это то, что все объекты, на которые ссылается сериализуемый объект, также должны быть помечены как сериализуемые. Если этого не сделать, при попытке сериализатора сериализовать немаркированный объект будет сгенерировано исключение.

У меня вопрос: почему применяется это ограничение? (Если это ограничение! ;-))


person CSharper    schedule 24.01.2016    source источник
comment
Это потому, что BinaryFormatter явно проверяет наличие этого атрибута и генерирует исключение, если оно отсутствует.   -  person user4003407    schedule 24.01.2016
comment
@PetSerAl Это не вопрос. вопрос: почему применяется это ограничение? (Если это ограничение! ;-))   -  person Sriram Sakthivel    schedule 24.01.2016
comment
Двоичная сериализация также сериализует частные поля. Это может иметь непредвиденные последствия для некоторых объектов. Есть некоторые библиотеки, которые вы можете использовать, если вам нужно преодолеть это. Это не обязательно ответ на вопрос. Просто комментарий.   -  person Tim Snow    schedule 24.01.2016


Ответы (2)


BinaryFormatter имеет очень необычные возможности, ничто другое не похоже на то, что он делает. Он может создать объект вашего класса без запуска его конструктора. И он может дать значение вашим свойствам без запуска методов доступа установщика свойств.

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

Не каждый класс подходит для такого обращения либо из соображений безопасности, либо из-за того, что значения полей слишком сильно зависят от состояния выполнения. Обратите внимание, насколько важна безопасность, поскольку злоумышленник может манипулировать сериализованными данными и привести ваш объект в несогласованное состояние, которое можно использовать. Скажем, свойство IsAdministrator. Хорошим примером критического состояния выполнения является свойство Control.Handle, оно никогда не может иметь то же значение при десериализации.

Это практические ограничения, которые класс BinaryFormatter не может решить сам по себе. Ему нужна помощь, явное подтверждение того, что это безопасно. Это не может быть формальным нормой, когда вы пишете код для де / сериализации объекта, это было бы легко, но на практике вы недостаточно знаете о классе, поскольку вы его не писали. Это необходимо автору класса, он делает это, задавая ему атрибут [Serializable].

person Hans Passant    schedule 24.01.2016

Я считаю, что ответ на https://stackoverflow.com/a/12461510/5830656 отвечает на ваш вопрос о том, почему это ограничение применяемый -

"для предотвращения случайной утечки данных через границу удаленного взаимодействия"

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

В этой статье MSDN также говорится:

после компиляции класс нельзя сделать сериализуемым.

(имеется в виду попытка сделать его сериализуемым во время выполнения путем добавления типа атрибута с использованием отражения), поэтому для реализации BinaryFormatter необходимо указать атрибут SerializableAttribute для компиляции типов, которые будут сериализованы с его использованием.

person jjee    schedule 24.01.2016
comment
Следует добавить логическое свойство RunsInSafeMode в BinaryFormatter! - person CSharper; 24.01.2016