Правильное устаревание старых членов класса XML Serializable в C# VB .NET

Некоторое время назад я определил класс, сериализованный с помощью XML. Этот класс содержал сериализуемое свойство Alignment целочисленного типа. Теперь я расширил и обновил этот класс, в результате чего было добавлено новое свойство Position, тип которого является другим классом, который также имеет несколько сериализуемых свойств. Новое свойство Position теперь должно взять на себя роль старого свойства Alignment, то есть, поскольку типом свойства Position является другой класс, один из его элементов будет содержать значение, которое ранее содержалось в свойстве Alignment, что делает свойство Alignment устаревшим.

Я пытаюсь выяснить, как мне убедиться, что при десериализации старой версии этого класса (без свойства Position в нем) я удостоверюсь, что десериализатор возьмет значение свойства Alignment из старого класса и установит это как значение одного из членов свойства Position в новом классе?

Private WithEvents _Position As Position = New Position(Alignment.MiddleMiddle, 0, True, 0, True)
Public Property Position() As Position 'NEW composite property that holds the value of the obsolted property, i.e. Alignment
    Get
        Return _Position
    End Get
    Set(ByVal value As Position)
        _Position = value
    End Set
End Property

Private _Alignment As Alignment = Alignment.MiddleMiddle
<Xml.Serialization.XmlIgnore(), Obsolete("Use Position property instead.")> _
Public Property Alignment() As Alignment 'The old, obsoleted property that I guess must be left for compliance with deserializing the old version of this class
    Get
        Return _Alignment
    End Get
    Set(ByVal value As Alignment)
        _Alignment = value
    End Set
End Property

Извините, но код написан на VB, но он в равной степени применим и к C#, и к любому другому языку .NET.

Не могли бы вы мне помочь?


person Fit Dev    schedule 11.06.2010    source источник


Ответы (3)


Вы можете использовать события XMLSerializer, чтобы помочь вам:

http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlserializer_events.aspx

Код будет выглядеть так:

    XmlSerializer xs = new XmlSerializer(typeof(MyClass));
    xs.UnknownAttribute += new XmlAttributeEventHandler(xs_UnknownAttribute);
    xs.UnknownElement += new XmlElementEventHandler(xs_UnknownElement);
    xs.UnknownNode += new XmlNodeEventHandler(xs_UnknownNode);
    xs.UnreferencedObject += 
       new UnreferencedObjectEventHandler(xs_UnreferencedObject);

Каждое событие имеет соответствующие аргументы события с очень подробной информацией о рассматриваемом узле/атрибе/элементе, так что более чем достаточно, чтобы вы могли определить, что делать.

person code4life    schedule 12.06.2010

Если ваш класс реализует IXmlSerializable вы можете добиться того, чего хотите, поскольку теперь у вас будет полный контроль над сериализацией и десериализацией вашего класса. Это позволит вам обрабатывать объекты, сериализованные до нового свойства Position, однако реализация IXmlSerializable — это PITA, потому что это подход «все или ничего».

person João Angelo    schedule 12.06.2010

Вы можете сохранить свойство Alignment и использовать его как псевдоним свойства Position. Если вы пометите его [ObsoleteAttribute], это предупредит пользователей вашего класса, что свойство устарело и его больше нельзя использовать. В какой-то момент вы сможете полностью отказаться от поддержки устаревшего свойства. Это устраняет проблемы совместимости как с сериализацией, так и с общедоступным интерфейсом.

person Dan Bryant    schedule 12.06.2010