Обработка XML-сериализации полей только для чтения в C # - PullRequest
2 голосов
/ 13 августа 2010

У меня есть класс, у которого определено свойство только для чтения, которое на самом деле является ссылкой на очень изменчивый объект, и мне интересно, как лучше всего обработать его сериализацию.

Например:

public class classA {
  public readonly classB B = new classB();
}

public class classB {
  public string Name = "Test";
}

Это можно сериализовать (если это не так, поле 'B' доступно только для чтения)

<classA>
  <B>
    <Name>Test</Name>
  </B>
</classA>

но я не могу десериализовать его, так как сериализатор попытается создать новый экземпляр класса B и установить поле в classA для этого нового объекта.

Если я сделаю свойство не доступным только для чтения, это откроет возможность для клиентского кода изменить используемый экземпляр класса B, что недопустимо (многие другие объекты будут иметь скрытые события в этом экземпляре, поэтому он может ' т просто заменить, как это). В качестве альтернативы, я мог бы заставить установщик просто скопировать значения из данного объекта в экземпляр, который уже существует, но это кажется чрезмерно громоздким только для размещения сериализатора.

Я подумал о том, чтобы иметь отдельное свойство с установщиком для обработки сериализации и установить его в [Browsable (BrowsableState.Never)], но это все еще предоставляет возможность изменить экземпляр любому, кто станет умным с отражением.

Есть ли способ указать сериализатору заполнить существующий объект при десериализации или мне придется создать собственный сериализатор?

Ответы [ 2 ]

3 голосов
/ 13 августа 2010

Ну, IXmlSerializable - это опция , но она не желательна;довольно сложно написать надежную реализацию чего-либо нетривиального.

Если иметь неизменяемое свойство , что важно, то, возможно, стоит рассмотреть возможность отдельной реализации DTO - то есть одного набора1010 * simple , изменяемые классы для персистентности, которые вы переводите в сущности вашего домена.

В качестве альтернативы могут помочь некоторые другие сериализаторы;например, DataContractSerializer будет работать в приватных полях:

[DataContract]
public class classA {
    [DataMember]
    private classB b = new classB();

    public classB B { get {return b; } }
}
0 голосов
/ 13 августа 2010

К сожалению, я не могу найти способ использовать собственный сериализатор XML для решения вашей ситуации. Тем не менее, я считаю, что двоичная сериализация будет работать в этом случае, если это вариант.

...