.NET Binary Serialize объект со ссылками на другие объекты. , , что просходит? - PullRequest
2 голосов
/ 05 февраля 2011

Если у вас есть экземпляр объекта A, который ссылается на другие объекты (например, экземпляры B и C), и вы двоично сериализуете A в файл, что произойдет?Есть ли у вас теперь сериализованные данные, которые включают A, B и C?

Как это работает точно?Что я получу, если буду десериализовать данные?A, B и C ??

(не стесняйтесь включать также объяснения внутренней работы).

Ответы [ 3 ]

7 голосов
/ 05 февраля 2011

Все ссылки на другие объекты также будут сериализованы. Если вы десериализуете данные, вы получите полный рабочий набор их данных, включая объекты A, B и C Вероятно, это основное преимущество двоичной сериализации, а не XML-сериализации.

Если любой из других классов, на которые ссылается ваш объект, не помечен атрибутом [Serializable] , вы получите SerializationException во время выполнения ( изображение которого было бесстыдно украдено из Интернета; ошибки времени выполнения даже не выглядят так в текущих версиях VS):

Example of an unhandled SerializationException

Кроме того, я не совсем уверен, какие "внутренние вещи" вы надеялись понять. Сериализация использует отражение для обхода открытых и закрытых полей объектов, превращая их в поток байтов, которые в конечном итоге записываются в поток данных. Во время десериализации происходит обратное: поток байтов считывается из потока данных, который используется для синтеза точной копии объекта вместе с информацией о типе. Все поля в объекте имеют те же значения, что и раньше; конструктор не вызывается при десериализации объекта. Самый простой способ думать об этом - просто взять 1010 * снимок на месте объекта, который вы можете восстановить в исходное состояние по желанию.

Класс, отвечающий за фактическую сериализацию и десериализацию, называется форматером (он всегда наследуется от IFormatter интерфейса ). Его задача - создать «граф объектов», который представляет собой обобщенное дерево, содержащее объект, сериализуемый / десериализованный как его корень. Как упомянуто выше, средство форматирования использует отражение, чтобы пройти через этот граф объектов, сериализовав / десериализовав все ссылки на объекты, содержащиеся в этом объекте. Форматировщик также достаточно умен, чтобы знать, что сериализовать какой-либо объект в графе не нужно более одного раза. Если две ссылки на объект фактически указывают на один и тот же объект, это будет обнаружено, и этот объект будет сериализован только один раз. Эта и другая логика не позволяют войти в бесконечный цикл.

Конечно, легко понять, как работает этот процесс. На самом деле намного сложнее написать код, который реализует его самостоятельно. К счастью, это уже сделано для вас. Отчасти .NET Framework заключается в том, что вся эта сложная логика сериализации встроена, что избавляет вас от беспокойства об этом. Я не претендую на то, что понимаю все это сам, и вам, конечно, не нужно ни использовать все возможности, которые он предлагает. Годы написания всего этого кода вручную окончены. Вы должны радоваться, а не беспокоиться о деталях реализации. : -)

4 голосов
/ 05 февраля 2011

Во-первых, тип объекта 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.

1 голос
/ 05 февраля 2011

Объекты, на которые ссылается главный объект, также должны быть [Serializable]. При условии, что все выполняется автоматически форматером.

...