2016-08-14 84 views
1

每当我遇到这个属性,我总是看到这样的用法:DataContract秘密行为?

[DataContract] 
class DataTransferObject 
{ 
    [DataMember] 
    public int Value {get;set;} 
} 

而且在这个例子中所有继承的成员应适用的DataMember属性为每个属性或领域,这可能导致非常笨拙和poilerplate代码。但是,最近我发现(也许秘密功能?)用它的一个非常优雅的方式:

[DataContract] 
public abstract class DTOBase 
{ 
} 

public class MyDTO : DTOBase 
{ 
    public int Value {get;set;} 

    public MyDTO(){} //important part is here 
} 

重要的部分:你应该总是明确定义参数构造函数,否则将无法正确序列化。

是的。它序列化其所有公共成员,不管多深将继承,而无需将属性应用于成员或类定义。

这是不知何故记录在某处(我没有找到)?因为,我非常支持可以避免多少样板文件。

回答

2

实际上,如果你不想要,你不需要使用DataContractDataMember属性,但是它们给你灵活定义什么需要序列化和如何。

我建议从文章Serializable Types on MSDN开始,它有很多关于Data Contract串行器如何工作的信息。这里是第一段落2,证明你不需要使用属性:

默认情况下,DataContractSerializer的序列化的所有公开可见 类型。

该类型的所有公共读/写属性和字段都是 序列化的。您可以通过将 DataContractAttribute和DataMemberAttribute属性应用于 和成员类型来更改默认行为。此功能在您的 类型不受您控制并且无法修改为添加 属性的情况下非常有用。 DataContractSerializer可识别这种“未标记”的 类型。

适用于你的情况主要规则是:

  • DataContract属性不会被继承。你可以在你的基类DTOBase上应用它,也可以不在你的基类MyDTO中忽略它。您可以从DTOBase类中删除DataContract属性,结果将相同。
  • 如果您在类中使用DataContract属性,则只有具有DataMember属性的成员才会被序列化。这就是您的第一个示例中DataTransferObject类中发生的情况。
  • 如果您没有在类上使用DataContract属性,则会对所有类的公共成员进行序列化。这是您的班级MyDTO发生的情况。