2011-11-28 2 views
3

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

Если да, то это не очень очень сосать, так как он ослабляет (если не ломается полностью) какой-либо инкапсуляции моего класса?

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

Я видел DLL для «порта» XStream для .net, но нет документов, и я подозрительный.

+0

Если я хорошо помню, я думаю, что геттер должен быть открытым, но не сеттер. – Exort

ответ

3

Вы должны использовать 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

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

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

Смежные вопросы