Я пытаюсь найти лучший способ сохранить (сериализовать), а затем открыть (десериализовать) древовидную структуру. Моя структура состоит из различных типов объектов с разными свойствами, но каждый наследуется от базового абстрактного класса «Узел».
Каждый узел имеет уникальный идентификатор (GUID) и метод AddSuperNode (Node nd), который устанавливает родительский элемент узла. Это, в свою очередь, вызывает другие методы, которые позволяют родительскому узлу узнать, какие подузлы у него есть. Однако некоторые узлы также используют метод AddAuxSuperNode (), который добавляет к узлу вторичного родителя.
Я использовал двоичную сериализацию, но теперь я думаю, что хочу использовать что-то, где у меня есть немного больше контроля, и сериализованные данные более доступны. Я также хочу сохранить информацию о типе при десериализации и иметь возможность сериализовать частные значения. Таким образом, DataContractSerializer казался лучшим вариантом.
Я не могу просто сериализовать корневой узел напрямую, потому что у узлов несколько родителей. Я не хочу создавать повторяющиеся объекты. Казалось бы, мне нужно деконструировать дерево в плоский список, а затем сериализовать его. Затем после сериализации этого списка реконструируйте дерево. Это звучит правильно?
Как я уже сказал, каждый узел имеет уникальный идентификатор GUID, но сейчас узлы напрямую ссылаются на своих родителей / детей и не хранят свои идентификаторы. Я мог бы обновить методы AddSuperNode () и AddAuxSuperNode (), чтобы также обновить список родительских идентификаторов для сериализации в дополнение к прямым ссылкам. Но я бы предпочел обновлять / создавать этот список только тогда, когда объект сериализуется. Итак, я подумал о создании метода UpdateSuperNodeIDRefs () в узле, который будет вызываться прямо перед сериализацией.
Вот что я планирую сделать для сериализации и десериализации этой структуры. Может ли кто-нибудь предложить лучший / более чистый / более эффективный способ сделать это?
Сериализация
1) Укажите корневой узел древовидной структуры.
2) Разбейте древовидную структуру на плоский Словарь (Guid id, Node nd), где id - это guid для nd сильный>.
3) Вызовите UpdateSuperNodeIDRefs (); для каждого узла, чтобы обновить идентификаторы, которые он сохранил для своих родителей.
4) Сериализуйте Словарь узлов с помощью DataContractSerializer.
Десериализация
1) Десериализуйте Словарь узлов.
2) Пройдитесь по каждому узлу в Словаре, повторно подключив каждый к своим родителям. Для любых сохраненных родительских идентификаторов найдите соответствующие узлы в Словаре с соответствующими идентификаторами, вызовите AddSuperNode () или AddAuxSuperNode (), чтобы повторно подключить узел к его родителям.
3) Из любого узла в Словаре найдите корень структуры.
4) Верните корневой узел