XML 反序列化 - 如何在保持兼容性的同时用 class 替换值 属性?

XML deserialize - How to replace a value property by a class while keeping compatibility?

我有一个 class 具有大量 public 属性,其中有许多浮点值:

public class Foo
{
    ...
    public float Bar {get; set;}
    ...
}

class 被 XML 序列化导致

<Foo ...(Schema stuff)... >
    ...
    <Bar>7.34</Bar>
    ...
</Foo>

在后续版本中,我需要使用一些额外的非序列化信息来扩展每个浮点值,因此我创建了一个新的 class:

public class ExtFloat
{
    public float Value { get; set; }
    private (other information)
}

为了使 ExtFloat 在已经使用 Foo 的数千行代码中表现为浮点数 class 我添加了隐式转换器:

public static implicit operator float(ExtFloat ef)
{
    return ef.Value;
}

public static implicit operator ExtFloat(float f)
{
    ExtFloat ef = new ExtFloat();
    ef.Value = f;
    return ef;
}

到目前为止一切顺利,无需更改任何引用 foo 中浮点数的代码即可正常工作。但是 class 现在序列化为

<Foo ...(Schema stuff)... >
    ...
    <Bar>
        <Value>7.34</Value>
    </Bar>
    ...
</Foo>

这使得数百个旧 XML 文件不兼容。所以,我的问题是:如何控制 XML 序列化过程,以使现有 XML 文件中的 Bar 属性 反序列化为新文件的值 属性 class?

实际上有数百个属性,例如 Foo 中的 Bar,所以我想将每个属性的更改保持在最低限度。到目前为止,我只需要更换类型。

如果你使用的是基于XmlSerializer的序列化,那么有一个小技巧。

XmlText 属性应用于值 属性,如下所示:

[Serializable]
public class ExtFloat
{
    [XmlText]
    public float Value { get; set; }

    private (other information)
}

然后 XmlSerializer 会将 Value 属性 视为类型为 ExtFloat.

的所有序列化属性的节点值