C # XML-сериализация - ослабление инкапсуляции? - PullRequest
3 голосов
/ 28 ноября 2011

Правильно ли я считаю, что для того, чтобы C # мог сериализовать объект, я ДОЛЖЕН иметь открытое свойство для каждого поля, для которого необходимо сохранить его состояние?

Если это так, разве это не очень плохо, так как оно ослабляет (если не нарушает полностью) любую инкапсуляцию, которую имеет мой класс?

В Java XStream может выполнять итерацию по каждому непереходному полю и архивировать его. В C # такого не может быть, и, что еще хуже, такие вещи, как словари, вообще не сериализуются. Это все немного беспорядок, нет?

Я видел DLL для "порта" XStream к .net, но нет никаких документов, и я с подозрением.

Ответы [ 2 ]

3 голосов
/ 28 ноября 2011

Вам следует использовать DataContractSerializer и пометить каждое свойство / поле, которое вы хотите сериализовать, с помощью [DataMember]. Не имеет значения, являются ли ваши поля приватными или общедоступными. Кстати, вы можете сериализовать словари с ним ...

[DataContract]
public class MyClass
{
    [DataMember]
    private string _privateField;

    [DataMember]
    public int PublicProperty { get; set;}
}

Сериализация:

private static string SerializeXml<T>(T item)
{
    DataContractSerializer ser = new DataContractSerializer(item.GetType());

    StringBuilder sb = new StringBuilder();
    XmlWriterSettings settings = new XmlWriterSettings { OmitXmlDeclaration = true, ConformanceLevel = ConformanceLevel.Fragment };
    using (XmlWriter writer = new XmlWriter(sb, settings))
    {
        ser.WriteObject(writer, item);
    }
    return sb.ToString();
}

Найдите здесь различия между XmlSerializer и DataContractSerializer: http://www.danrigsby.com/blog/index.php/2008/03/07/xmlserializer-vs-datacontractserializer-serialization-in-wcf/

1 голос
/ 28 ноября 2011

Бинарный формататор сериализует частные и даже доступные только для чтения поля без необходимости в свойствах.XmlSerializer может сериализоваться только с открытым конструктором без аргументов и общими свойствами.Если вы хотите использовать XmlSerializer с инкапсуляцией, вы можете использовать IXmlSerializable, но это довольно болезненно.

Если ваша объектная модель достаточно проста или вы можете сделать ее довольно простой, введя специальные DTO: s для сериализации (например, дляизбегать структур), тогда я рекомендую использовать контрактный сериализатор, который может сериализовать частные поля или свойства.Посмотрите на protobuf-сеть.

...