DataContract 秘密行为?

DataContract secret behavior?

每次遇到这个属性,总是看到这样的用法:

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

并且在此示例中,所有继承的成员都应将 DataMember 属性应用于每个 属性 或字段,这会导致代码非常笨拙和样板化。但是,最近我发现(也许是秘密功能?)一种非常优雅的使用方式:

[DataContract]
public abstract class DTOBase
{
}

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

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

重要部分:你应该始终显式定义无参数构造函数,否则将无法正确序列化。

是的。它 序列化其所有 public 成员,无论继承的深度如何,无需将属性应用于成员或 class 定义。

这是否以某种方式记录在某处(我没有找到)?因为,我很惊讶可以避免多少样板文件。

实际上,如果您不想使用 DataContractDataMember 属性,但是它们使您可以灵活地定义需要序列化的内容和方式。

我建议从文章 Serializable Types on MSDN 开始,它有很多关于数据协定序列化程序如何工作的信息。这是前两段,证明你不需要使用属性:

By default, the DataContractSerializer serializes all publicly visible types.

All public read/write properties and fields of the type are serialized. You can change the default behavior by applying the DataContractAttribute and DataMemberAttribute attributes to the types and members This feature can be useful in situations in which you have types that are not under your control and cannot be modified to add attributes. The DataContractSerializer recognizes such "unmarked" types.

适用于您的案例的主要规则是:

  • DataContract 属性不被继承。您可以在基础 class DTOBase 上应用或不应用它,它在子 class MyDTO 中被忽略。您可以从 DTOBase class 中删除 DataContract 属性,结果将相同。
  • 如果您在 class 上使用 DataContract 属性,则只有具有 DataMember 属性的成员才会被序列化。这就是第一个示例中 class DataTransferObject 中发生的情况。
  • 如果您不在 class 上使用 DataContract 属性,那么 class 的所有 public 成员都会被序列化。这就是你的 class MyDTO.
  • 发生的事情