数据成员默认值

在 .NET Framework 中,类型具有默认值的概念。 例如,对于任何引用类型,默认值为 null,而整型的默认值为零。 如果某个数据成员设置为其默认值,有时会希望序列化数据中不包含该数据成员。 由于成员具有默认值,这个实际值不需要进行序列化;这样处理可以提高性能。

若要在序列化数据中忽略某个成员,请将 EmitDefaultValue 属性 (Attribute) 的 DataMemberAttribute 属性 (Property) 设置为 false(默认值为 true)。

备注

如果有特定需要(如实现互操作性或减小数据大小),应将 EmitDefaultValue 属性设置为 false

示例

下面的代码中,有几个成员的 EmitDefaultValue 设置为 false

[DataContract]
public class Employee
{
    [DataMember]
    public string employeeName = null;
    [DataMember]
    public int employeeID = 0;
    [DataMember(EmitDefaultValue = false)]
    public string position = null;
    [DataMember(EmitDefaultValue = false)]
    public int salary = 0;
    [DataMember(EmitDefaultValue = false)]
    public int? bonus = null;
    [DataMember(EmitDefaultValue = false)]
    public int targetSalary = 57800;
}
<DataContract()> _
Public Class Employee
    <DataMember()> _
    Public employeeName As String = Nothing
    <DataMember()> _
    Public employeeID As Integer = 0
    <DataMember(EmitDefaultValue:=False)> _
    Public position As String = Nothing
    <DataMember(EmitDefaultValue:=False)> _
    Public salary As Integer = 0
    <DataMember(EmitDefaultValue:=False)> _
    Public Bonus As Integer = Bonus OrElse Nothing
    <DataMember(EmitDefaultValue:=False)> _
    Public targetSalary As Integer = 57800
End Class

如果序列化此类的实例,则结果如下:序列化 employeeNameemployeeIDemployeeName 的 null 值和 employeeID 的零值显式成为序列化数据的一部分。 但是,positionsalarybonus 成员没有被序列化。 最后,即使 targetSalary 属性设置为 EmitDefaultValue,由于 57800 不是 .NET 的整数默认值零,false 还是照常被序列化。

XML 表示形式

如果上一个示例序列化为 XML,则表示形式类似于下面的内容。

<Employee>  
   <employeeName xsi:nil="true" />  
   <employeeID>0</employeeID>  
<targetSalary>57800</targetSalary>  
</Employee>  

xsi:nil 属性是万维网联合会 (W3C) XML 架构实例命名空间中的一个特殊属性,它提供一种显式表示 null 值的可互操作方式。 请注意,在 XML 中,没有 position、salary 和 bonus 数据成员的任何相关信息。 接收端可将它们分别解释为 null、零和 null。 无法确保第三方反序列化程序可以进行正确的解释,这就是不建议使用这种模式的原因。 DataContractSerializer 类始终为缺少的值选择正确的解释。

与 IsRequired 交互

数据协定版本控制中所述,DataMemberAttribute 特性具有 IsRequired 属性(默认值为 false)。 该属性 (Property) 指示,当某个给定数据成员进行反序列化时,该数据成员是否必须出现在序列化数据中。 如果 IsRequired 设置为 true(指示值必须存在)并且 EmitDefaultValue 设置为 false(指示如果值设置为其默认值,则该值不得存在),则由于结果相互矛盾,此数据成员的默认值无法序列化。 如果这样的一个数据成员被设置为其默认值(通常为 null 或零)并且尝试进行序列化,则会引发 SerializationException

架构表示形式

数据协定架构参考详细讨论了当 EmitDefaultValue 属性设置为 false 时,数据成员的 XML 架构定义语言 (XSD) 架构表示形式。 下面是简要概述:

  • EmitDefaultValue 设置为 false 时,它将在架构中表示为特定于 Windows Communication Foundation (WCF) 的注释。 没有用于表示此信息的可交互操作方式。 特别是,架构中的“default”属性不用于此目的,minOccurs 属性仅受 IsRequired 设置的影响,而 nillable 属性仅受数据成员类型的影响。

  • 要使用的实际默认值在架构中不存在。 由接收终结点负责对缺少元素进行适当解释。

导入架构时,每当检测到前述特定于 WCF 的注释时,EmitDefaultValue 属性都会自动设置为 false。 对于 false 属性设置为 nillable 的引用类型,该属性也设置为 false,以支持在使用 ASP.NET Web 服务时常遇到的特定互操作性方案。

请参阅