Поиск ссылок в IXmlSerializable - PullRequest
       18

Поиск ссылок в IXmlSerializable

1 голос
/ 07 января 2010

Я пишу элементы определенного типа в исходящий xml с помощью IXmlSerializable. Я реализовал схему и пишу элементы. Код, приведенный ниже, является примером.

public void IXmlSerializable.WriteXml(XmlWriter writer) {
  // Write Out Class.
  foreach (var item in myItems) {
    DataContractSerializer ds = new DataContractSerializer(typeof(MyType));
    ds.WriteObject(writer, item);
  }
}

У меня проблема в том, что MyType объявлен с использованием ссылок

[DataContract(IsReference = true)]
public class MyType { ...

Таким образом, когда элемент уже записан в xml, он должен быть ссылкой.

Как узнать, была ли ссылка на xml уже записана? Я придерживаюсь мнения, что я должен просто игнорировать ссылки, которые я явно не контролирую. Таким образом, я буду создавать свои собственные ссылочные идентификаторы и ссылаться на свои собственные экземпляры.

Это явно плохой взломанный компромисс, поскольку я дублирую ссылки, которые не должны дублироваться.

Есть ли способ узнать, что уже написано, чтобы узнать, смогу ли я найти идентификатор для уже сериализованного элемента?

Привет

Craig.

1 Ответ

0 голосов
/ 27 апреля 2012

Магия «IsReference» работает только для сериализаций в пределах одного «эпизода». Эпизод - это один вызов WriteObject.

Допустим, у вас должен был быть объект верхнего уровня некоторого типа верхнего уровня, как показано ниже:

[DC]    
class Container
    {
      [DM]
      MyType i1 = new MyType();
      [DM]
      MyType i2 = i1;;
      [DM]
      MyType i3 = i1;
    }

Теперь, если вы хотите сериализовать экземпляр Container через вызов WriteObject, то есть когда в игру вступают «ids» и «refs». Когда сериализуется i1, он сериализуется с идентификатором 1, но когда сериализуются i2 и i3, каждый из них сериализуется с атрибутами «REF», указывающими обратно на идентификатор 1 MyType.

В вашем примере, поскольку каждый вызов WriteObject представляет собой отдельный эпизод, каждый вызов сериализует весь граф объектов. Если вы не можете упаковать все свои различные экземпляры MyType в объект более высокого уровня (или даже коллекцию), вам не повезло. Вот что вам нужно сделать - по сути, заставить все экземпляры MyType быть сериализованными в рамках одного вызова WriteObject более высокого уровня.

...