.NET Binary Serialize объект со ссылками на другие объекты...что случилось?
-
29-10-2019 - |
Вопрос
Если у вас есть экземпляр объекта A, который ссылается на другие объекты (например, экземпляры B и C), и вы двоично сериализуете A в файл, что произойдет?У вас есть сериализованные данные, которые включают A, B и C?
Как именно это работает?Что я получу, если десериализую данные?A, B и C ??
(Не стесняйтесь также включать пояснения по внутренней работе).
Решение
Все ссылки на другие объекты также будут сериализованы. Если вы десериализуете данные, вы получите полный рабочий набор их данных, включая объекты A, B и В. Вероятно, это основное преимущество двоичной сериализации по сравнению с сериализацией XML.
Если какой-либо из других классов, на которые ссылается ваш объект, не отмечен знаком [Serializable]
attribute , вы получите сгенерировать код кода во время выполнения (изображение которого было беззастенчиво украдено из Интернета; ошибки времени выполнения больше не выглядят так в текущих версиях VS):
Кроме того, я не совсем уверен, какие «внутренние вещи» вы хотели понять. Сериализация использует отражение для просмотра общедоступных и частных полей объектов, преобразовывая их в поток байтов, которые в конечном итоге записываются в поток данных. Во время десериализации происходит обратное: поток байтов считывается из потока данных, который используется для синтеза точной копии объекта вместе с информацией о типе. Все поля в объекте имеют те же значения, что и раньше; конструктор не вызывается при десериализации объекта. Самый простой способ подумать об этом - это просто сделать моментальный снимок на месте объекта, который можно по желанию восстановить в исходное состояние.
Класс, который отвечает за фактическую сериализацию и десериализацию, называется средством форматирования (он всегда наследуется от SerializationException
interface ). Его задача - создать «граф объектов», который представляет собой обобщенное дерево, содержащее сериализуемый / десериализованный объект в качестве его корня. Как упоминалось выше, средство форматирования использует отражение для обхода этого графа объекта, сериализации / десериализации всех ссылок на объекты, содержащихся в этом объекте. Форматировщик также достаточно умен, чтобы знать, что нельзя сериализовать какой-либо объект на графике более одного раза. Если две объектные ссылки на самом деле указывают на один и тот же объект, это будет обнаружено, и этот объект будет сериализован только один раз. Эта и другая логика предотвращает попадание в бесконечный цикл.
Конечно, легко получить общее представление о том, как работает этот процесс. На самом деле намного сложнее написать код, реализующий это самостоятельно. К счастью, это уже было сделано за вас. Отчасти суть .NET Framework заключается в том, что вся эта сложная логика сериализации встроена, поэтому вы можете не беспокоиться об этом. Я не утверждаю, что понимаю все это сам, и вам, конечно же, не нужно этого делать, чтобы в полной мере использовать возможности, которые он предлагает. Наконец-то закончились годы написания всего этого кода вручную. Вы должны радоваться, а не беспокоиться о деталях реализации. :-)
Другие советы
Во-первых, тип объекта A должен быть помечен атрибутом [Serializable].Сериализация A будет сериализовать все его данные-члены, частные или общедоступные, при условии, что типы членов также помечены [Serializable] (или, используя ваш пример, при условии, что типы B и C отмечены [Serializable]).Попытки сериализовать данные, прямо или косвенно, типа, не являющегося [Serializable], приведут к исключению.
Некоторые встроенные типы .NET уже помечены как [Serializable], включая System.Int32 (int), System.Boolean (bool) и т. д.
Подробнее о сериализации .NET можно прочитать здесь: http:// msdn.microsoft.com/en-us/library/4abbf6k0.aspx .
Объекты, на которые ссылается главный объект, также должны быть [сериализуемыми].При этом все выполняется автоматически форматировщиком.