反序列化未知类型

本文关键字:类型 未知 反序列化 | 更新日期: 2023-09-27 18:20:24

我有以下XML:

<property name="someName" value="someValue" />

或者,这可以是:

<property name="someName" value="5" />

或者:

<property name="someName" value="true" />

等等…

[Serializable]
[XmlType("property")]
public class Property
{
    [XmlAttribute("name")]
    public string Name { get; set; }
    [XmlAttribute("value")]
    public object Value { get; set; }
    public Property()
    {
    }
}

上面的代码不起作用。我可以使用字符串,或者任何特定的东西,只要它总是那个特定的类型。我希望这个物体能允许任何已知类型的作品。

反序列化未知类型

除非使用IXmlSerializable接口实现自定义序列化并手动处理这种情况,否则无法使用XmlSerializer将对象用作属性的数据类型。如果没有将Value属性序列化为属性,则可以使用XmlInclude来指定可能的已知类型(如int、bool、string…),并且序列化程序将在XML上发出一个附加属性来指定确切的类型,以便知道如何反序列化。但所有这些都不适用于您的场景,因为您正在使用一个属性。不幸的是,您将不得不重新考虑您的XML结构或使用自定义序列化。XmlSerializer根本无法处理这种情况。

另一种可能性是将此属性定义为String并进行后序列化处理。甚至可能在模型上定义另一个只有getter的属性,并且基于该字符串的值可能会尝试将其解析为某个底层类型。

那么,xml序列化程序如何知道您要存储字符串"5"还是实际的数字5?您要么需要实现IXmlSerializable接口,要么可以应用一个变通方法:

[Serializable]
[XmlType("property")]
public class Property
{
    [XmlAttribute("name")]
    public string Name { get; set; }
    [XmlAttribute("value")]
    public string StringValue { get; set; }
    private object _Value;
    [XmlIgnore]
    public object Value
    {
        get
        {
            if (_Value == null)
            {
                 _Value = CreateFromStringValue();
            }
            return _Value;
        }
    }
    public Property()
    {
    }
    private object CreateFromStringValue()
    {
       // parse StringValue in here as you see fit (e.g. first try bool, then int, float, etc.)
    }
}

没有那么好,但可能是你所需要的。