#1和#2之间的基本区别在于,它们生成不同的
XML Schemas
。如果希望从类型的架构中排除成员,请使用
[XmlIgnore]
。如果希望有条件地包括成员,请使用
ShouldSerializeXXX()
XXXSpecified
(最后,如
this answer
,
[NonSerialized]
在选项中#3被忽略
XmlSerializer
要查看#1和#2之间的差异,可以使用
xsd.exe
为类型生成模式。以下模式是为版本#1生成的,完全省略了
Name
成员:
<xs:complexType name="Item" />
名称
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="1" name="Name" type="xs:string" />
</xs:sequence>
产生差异的原因是
和
两者都执行
静态类型分析
而不是
动态代码分析
。两种工具都无法确定
在#2的情况下,属性将始终被跳过,因为两个工具都没有尝试反编译的源代码
ShouldSerializeName()
false
因此
将出现在版本#2的架构中,尽管在实践中从未出现过。如果随后创建web服务并使用发布模式
WSDL
(或者简单地手动提供),将为这两种类型生成不同的客户端——一种没有
名称
成员和一个。
当所讨论的属性是不可为null的值类型时,可能会产生额外的复杂性。考虑以下三个版本的
Item
public class Item
{
public int Id { get; set; }
}
使用生成以下架构
Id
始终存在:
<xs:complexType name="Item">
<xs:sequence>
<xs:element minOccurs="1" maxOccurs="1" name="Id" type="xs:int" />
</xs:sequence>
</xs:complexType>
public class Item
{
[XmlIgnore]
public int Id { get; set; }
}
生成以下模式,该模式完全省略了
身份证件
属性:
<xs:complexType name="Item" />
public class Item
{
public int Id { get; set; }
public bool ShouldSerializeId()
{
return false;
}
}
使用生成以下架构
<xs:complexType name="Item">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="1" name="Id" type="xs:int" />
</xs:sequence>
</xs:complexType>
模式#2与预期的一样,但请注意#1和#3之间有一个区别:第一个有
minOccurs="1"
minOccurs="0"
.产生差异的原因是
XmlSerializer
是
documented
null
默认值,但对于不可为null的值成员没有类似的逻辑。因此
身份证件
案例#1中的属性将始终序列化,因此
在模式中指示。只有在启用条件序列化时
最小值=“0”
IdSpecified
属性将添加到自动生成的代码中,以跟踪
身份证件
在反序列化过程中实际遇到了属性:
public partial class Item {
private int idField;
private bool idFieldSpecified;
/// <remarks/>
public int Id {
get {
return this.idField;
}
set {
this.idField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlIgnoreAttribute()]
public bool IdSpecified {
get {
return this.idFieldSpecified;
}
set {
this.idFieldSpecified = value;
}
}
}
有关绑定到条件序列化值成员的更多详细信息,请参阅
XML Schema Binding Support: MinOccurs Attribute Binding Support
和
ShouldSerialize*() vs *Specified Conditional Serialization Pattern
这是主要区别,但也有次要区别,可能会影响您的选择:
-
[XmlIgnore]
不能在派生类中重写,但
ShouldSerializeXXX()
here
例如。
-
XmlSerializer
因为,例如,它引用了一种类型
lacks a parameterless constructor
,然后用
[XmlIgnore]
ShouldSerializeXXX() { return false; }
XmlSerializer
仅执行静态类型分析。E、 g.以下内容:
public class RootObject
{
// This member will prevent RootObject from being serialized by XmlSerializer despite the fact that the ShouldSerialize method always returns false.
// To make RootObject serialize successfully, [XmlIgnore] must be added.
public NoDefaultConstructor NoDefaultConstructor { get; set; }
public bool ShouldSerializeNoDefaultConstructor() { return false; }
}
public class NoDefaultConstructor
{
public string Name { get; set; }
public NoDefaultConstructor(string name) { this.Name = name; }
}
无法由序列化
.
-
特定于
但是
ShouldSerializeXXX()
Json.NET
和
protobuf-net
.
-
ShouldSerializeXXX()
方法名称,导致潜在的维护问题。