【问题标题】:C# XML Serialization - weakening encapsulation?C# XML 序列化 - 削弱封装?
【发布时间】:2011-11-29 00:08:20
【问题描述】:

我是否正确地认为,为了让 C# 序列化一个对象,我必须为每个需要存储其状态的字段拥有一个公共属性?

如果是这样,那是不是很糟糕,因为它削弱了(如果不是完全破坏)我的课程的任何封装?

在 Java 中,XStream 可以遍历每个非瞬态字段并将其归档。在 C# 中这不可能发生,而且更糟的是,像字典这样的东西根本不会序列化。有点乱,不是吗?

我已经看到了 XStream 到 .net 的“端口”的 DLL,但没有文档,我很怀疑。

【问题讨论】:

  • 如果我没记错的话,我认为 getter 必须是 public 而不是 setter。

标签: c# .net serialization encapsulation xstream


【解决方案1】:

您应该使用 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/

【讨论】:

    【解决方案2】:

    binaryformatter 无需属性即可序列化私有甚至只读字段。 XmlSerializer 只能使用公共无参数构造函数和公共属性进行序列化。如果你想使用带有封装的 XmlSerializer,你可以使用 IXmlSerializable,但那是相当痛苦的。

    如果您的对象模型相当简单,或者您可以通过引入特殊的 DTO:s 进行序列化来使其相当简单(例如,避免使用结构),那么我建议使用可以序列化私有字段或属性的基于协定的序列化程序。看看protobuf-net。

    【讨论】:

      猜你喜欢
      • 2016-11-03
      • 2014-07-17
      • 2011-08-19
      • 2011-05-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多