为啥 DataMemberAttribute 需要对布尔属性进行特殊处理
Posted
技术标签:
【中文标题】为啥 DataMemberAttribute 需要对布尔属性进行特殊处理【英文标题】:Why Does the DataMemberAttribute Require Special Handling for Boolean Properties为什么 DataMemberAttribute 需要对布尔属性进行特殊处理 【发布时间】:2013-09-30 09:37:44 【问题描述】:我注意到,如果数据协定中的布尔属性不发出默认属性,例如
[DataMember(Order = 0, IsRequired = true, EmitDefaultValue = false)]
public bool IsSet get; set;
然后将该属性设置为 false 会导致序列化错误。这似乎违反直觉,因为属性已经设置,只是它被设置为 false。解决方案是始终将布尔属性配置为发出默认值,然后 true 将通过线路作为 true,而 false 将作为 false。
只是好奇:这是 System.Runtime.Serialization 中的错误还是布尔类型语义的必然结果?
【问题讨论】:
【参考方案1】:您的问题有点令人困惑,但我认为您似乎看到的行为不是错误,也不是与布尔值有关。
操作合约被标记为IsRequired
设置为true。默认情况下,EmitDefaultValue
设置为 true,但在发布的代码中,它被设置为 false。
EmitDefaultValue
属性指示是否序列化该值,如果它是默认值(换句话说,如果属性设置为false
,它不会根据您当前的定义序列化该属性)。
由于该属性被标记为必需,如果您将值设置为false
,则序列化将失败(如果EmitDefaultValue
为假),因为您给出了相互矛盾的指示 - 您是说该属性是序列化所必需的, 但如果是默认值(false)就不要序列化。
在某种程度上我猜你可能会说这是因为布尔值的性质(它要么是真要么是假,而假是默认值),但实际上这是因为IsRequired
和EmitDefaultValue
交互的方式。
查看Data Member DefaultValues,特别是“与 IsRequired 的交互”部分。
【讨论】:
我明白你在说什么。 EmitDefaultValue 不关心该值是否已显式分配,只关心该属性的值是否等于该类型的默认值。所以整数的工作原理是一样的:所有值为 0 的整数都将从序列化中删除,除非 EmitDefaultValue 为 true。 正确。请记住,在 .NET 中,变量在声明时确实具有默认值 - 值类型的值(如 int 的 0)和引用类型的 null。使用自动属性时,编译器将为您创建支持字段,因此如果您不明确设置属性,它将具有相应的默认值。【参考方案2】:为避免冲突,您可以使用可为空的 bool (bool?),因此如果该值显式设置为 false,它将按预期进行序列化。当然,请确保您的系统可以处理可为空的 bool 数据类型。
[DataMember(Order = 0, IsRequired = true, EmitDefaultValue = false)]
public bool? IsSet get; set;
【讨论】:
以上是关于为啥 DataMemberAttribute 需要对布尔属性进行特殊处理的主要内容,如果未能解决你的问题,请参考以下文章
如何获取具有指定名称的 DataMemberAttribute 的属性?