XmlSerializer 和可为空的属性

Posted

技术标签:

【中文标题】XmlSerializer 和可为空的属性【英文标题】:XmlSerializer and nullable attributes 【发布时间】:2011-03-16 02:36:48 【问题描述】:

我有一个具有许多 Nullable 属性的类,我希望将其作为属性序列化为 XML。这显然是一个禁忌,因为它们被认为是“复杂类型”。因此,我实现了 *Specified 模式,在其中创建了一个附加的 *Value 和 *Specified 属性,如下所示:

[Xml忽略] 公共诠释?年龄 得到返回这个年龄; 设置 this.age = value; [XmlAttribute("年龄")] 公共 int AgeValue 得到 返回 this.age.Value; 设置 this.age = value; [Xml忽略] 公共布尔年龄值指定 得到 返回 this.age.HasValue;

这很好——如果“年龄”属性有一个值,它会被序列化为一个属性。如果它没有值,则不会序列化。

问题是,正如我所提到的,我的班级中有很多 Nullable-s,这种模式只会让事情变得混乱和难以管理。

我希望有一种方法可以让 Nullable 对 XmlSerializer 更加友好。或者,如果做不到这一点,一种创建 Nullable 替换的方法是。

有人知道我该怎么做吗?

谢谢。

【问题讨论】:

【参考方案1】:

我在处理一些代码时遇到了类似的问题,我决定只为我正在序列化和反序列化的属性使用一个字符串。我最终得到了这样的结果:

[XmlAttribute("Age")]
public string Age

    get 
     
        if (this.age.HasValue)
            return this.age.Value.ToString(); 
        else
            return null;
    
    set 
     
        if (value != null)
            this.age = int.Parse(value);
        else
            this.age = null;
    


[XmlIgnore]
public int? age;

【讨论】:

这仍然是可空属性的最佳解决方案吗?【参考方案2】:

在你的类上实现IXmlSerializable 接口。然后,您可以在 ReadXMLWriteXML 方法中处理特殊情况,例如可为空值。 There's a good example in the MSDN documentation page..

 
class YourClass : IXmlSerializable

    public int? Age
    
        get  return this.age; 
        set  this.age = value; 
    

    //OTHER CLASS STUFF//

    #region IXmlSerializable members
    public void WriteXml (XmlWriter writer)
    
        if( Age != null )
        
            writer.WriteValue( Age )
        
    

    public void ReadXml (XmlReader reader)
    
        Age = reader.ReadValue();
    

    public XmlSchema GetSchema()
    
        return(null);
    
    #endregion

【讨论】:

我想这将不得不做 - 能够告诉“复杂”类型序列化为属性会很好。 如果你有很多属性但只有一个可以为空的,这不意味着手动序列化每个属性吗?对于可空属性,有没有一种好方法可以做到这一点? @Curt 答案中的 Proxy 属性可以做到这一点,但我认为属性装饰器必须存在?

以上是关于XmlSerializer 和可为空的属性的主要内容,如果未能解决你的问题,请参考以下文章

XmlConvert 和可为空的结果?

JPA 可嵌入 PK 和可为空的字段

XmlCodeExporter 和可为空的类型

Laravel 验证中有时和可为空的区别

将 XDocument.Descendants 与合并运算符一起使用??和可为空的类型

如何在基于块的 API 方法中使用非空和可为空的 Objective-C 关键字