Подтвердить что ты не робот

Что такое граф объекта и как его сериализовать?

В последнее время я читал о сериализации. Я читал, что, когда я использую XmlSerialization, я не могу сериализовать графы объектов. Что такое графа объектов и почему я не могу сериализовать его просто?

4b9b3361

Ответ 1

График объектов - это не один объект, а набор связанных объектов. Для простого примера рассмотрим:

public class Node {
    public string Name {...}
    public Node Parent {...}
    public List<Node> Children {...}
}

где каждый ребенок знает о родительском (и родитель знает о ребенке).

Проблема заключается в том, что xml - это дерево, основанное на объектных свойствах... и он хочет просто пройти их - то есть с простым родителем/дочерним:

  • A (знает, что B - его дочерний элемент)
    • B (знает, что A является его родителем)

который будет сериализоваться как:

<Node>
  <Name>A</Name>
  <!-- no Parent as A is the top node, so null -->
  <Children>
     <Node>
        <Name>B</Name>
        <Parent>
           <Node>
              <Name>A</Name>
              *** boom ***

Вы можете видеть, что мы вернулись к A, так что теперь мы находимся в бесконечном цикле.

XmlSerializer может сериализовать деревья данных, но не полные графики. Вы можете отметить игнорируемые свойства, например:

[XmlIgnore]
public Node Parent {...}

И теперь это сработает, но мы должны будем исправить Parent впоследствии.

В отличие от некоторых других сериализаторов могут обрабатывать графики (DataContractSerializer может по требованию). Он делает это, отслеживая объекты против уникального ключа, но тогда результат не является тем, что вы ожидаете от обычного xml.

Ответ 2

График объектов - это набор объектов, которые ссылаются друг на друга.

Сериализация графа объектов сложна. Сериализатор должен будет присваивать уникальный идентификатор каждому объекту, а затем заменять ссылки уникальными идентификаторами.

Если бы он был сериализован в формате XML и обрабатывал графы объектов, ему пришлось бы добавить атрибут "OBJECT_ID" (или какой-либо другой) для каждого элемента. Это было бы очень легко сломать: что произойдет, если вы добавите свойство с тем же именем в класс, который вы сериализуете?

Самое простое решение - не поддерживать его.

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

Ответ 3

Общий объект graph состоит из набора объектов, содержащих ссылки друг на друга. Если у вас есть дерево объектов, где нет обратных ссылок, сериализация и десериализация просты. С общим графиком процесс сериализации (de) должен отслеживать идентификацию каждого объекта и использовать некоторую форму алгоритма mark-and-sweep для обеспечения того, чтобы объекты не были (де) сериализованы дважды.