2016-10-24 7 views
1

У меня есть класс с большим количеством открытых свойств, среди них ряд значений с плавающей точкой:XML deserialize - Как заменить свойство value классом при сохранении совместимости?

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

Класс XML Сериализированная в результате

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

В последующих версиях мне нужно расширить каждое значение с плавающей точкой с некоторой дополнительной без сериализованной информации, поэтому я создал новый класс:

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

для того, чтобы сделать ExtFloat б ehave как поплавок в тысячи строк кода уже с помощью класса Foo я добавил неявные преобразователи:

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 ...(Schema stuff)... > 
    ... 
    <Bar> 
     <Value>7.34</Value> 
    </Bar> 
    ... 
</Foo> 

который делает сотни старых XML-файлов там несовместимыми. Итак, моя проблема: как мне управлять процессом сериализации XML, чтобы сделать свойство Bar в существующих файлах XML десериализованным в свойство Value нового класса?

В действительности существует сотни свойств, таких как Bar в Foo, поэтому я хочу сохранить изменения каждого из них как минимум. До сих пор мне приходилось только заменять тип.

+0

Какую сериализацию XML вы используете? 'DataContract' или "простой старый ваниль" 'XMLSerializer'? – dymanoid

ответ

0

Если вы используете сериализацию на основе XmlSerializer, то для этого есть небольшой трюк.

Применить атрибут XmlText к свойству значения, как это:

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

    private (other information) 
} 

XmlSerializer будет относиться к Value свойства в качестве значения узла для всех сериализованных свойств типа ExtFloat.

+0

Спасибо @dymanoid, он отлично работает, за исключением незначительной проблемы. Он становится зависимым от культуры, поэтому мне пришлось применить «CultureInfo.InvariantCulture» к моему собственному преобразованию. Однако, поскольку мой класс открывается через PropertyGrid, который должен быть осведомлен о культуре, мне пришлось добавить отдельное свойство (с '[XmlIgnore]') для сетки и отметить оригинал как '[Browsable (false)]' –