反序列化未知类型

3
我有以下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()
    {

    }
}

上述代码不起作用。只要它始终是特定类型,我可以使用字符串或任何具体内容。我希望对象允许任何已知类型的工作。

2
字符串可以适用于所有这些情况,但您必须在整个应用程序中将其视为字符串。这不是一个选项吗? - Rob Stevenson-Leggett
2个回答

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

另一种可能性是将此属性定义为字符串并进行后序列化处理。甚至可以在模型上定义另一个仅具有 getter 的属性,根据此字符串的值尝试将其解析为某些基础类型。


1

那么,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.)
    }
}

可能不够漂亮,但也许就是你所需要的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接