1

在 SO 上序列化 类型有多种解决方案,Nullable但我需要的是反序列化为可空类型的解决方案。Specified 和 ShouldSerailise 技术似乎不适用于反序列化。

因此,如果我的 XML 文档缺少一个属性,我希望类中的 int 为 null 而不是 0。

不幸的是,您不能直接序列化为可为空的 int,因为序列化会引发反射错误。

所以在下面的例子中,我想result2.SomeInt为 null 并且result1.SomeInt = 12

class TestProgram
{
    public static void Main(string[] args)
    {
        XmlSerializer deserializer = new XmlSerializer(typeof(Result));

        Stream xmlStream = new MemoryStream(Encoding.ASCII.GetBytes(docWithVal().InnerXml));
        var result1 = (Result)deserializer.Deserialize(xmlStream);

        Stream xmlStream2 = new MemoryStream(Encoding.ASCII.GetBytes(docWithoutVal().InnerXml));
        var result2 = (Result)deserializer.Deserialize(xmlStream2);
    }

    public static XmlDocument docWithoutVal()
    {
        var doc = new XmlDocument();
        doc.LoadXml(@"<Result/>");
        return doc;
    }

    public static XmlDocument docWithVal()
    {
        var doc = new XmlDocument();
        doc.LoadXml(@"<Result SomeInt = ""12""/>");
        return doc;
    }
}

[Serializable]
public class Result
{
    [XmlAttribute]
    public int? SomeInt { get; set; }
}
4

1 回答 1

1

您实际上可以在反序列化后使用指定的技术。以这种方式修改您的Result课程:

[Serializable]
public class Result
{
    [XmlAttribute]
    public int SomeInt { get; set; }

    [XmlIgnore]
    public bool SomeIntSpecified;
}

Nullable现在在反序列化类型后使用此逻辑:

var value = SomeIntSpecified ? SomeInt : null;

或者你也可以IXmlSerializable在你的Result类中实现:

[Serializable]
public class Result : IXmlSerializable
{
    public int? SomeInt { get; set; }

    #region IXmlSerializable members

    public void WriteXml(XmlWriter writer)
    {
        if (SomeInt != null) { writer.WriteValue(writer); }
    }

    public void ReadXml(XmlReader reader)
    {
        int result;
        if (int.TryParse(reader.GetAttribute("SomeInt"), out result))
            SomeInt = result;
    }

    public XmlSchema GetSchema()
    {
        return (null);
    }

    #endregion
}

参考:使用 XmlSerializer 反序列化为 Nullable

于 2012-11-14T15:05:00.690 回答