开发者

Properly obsoleting old members in an XML Serializable class in C# VB .NET

Sometime ago I defined a class that was serialized using XML. That class contained a serializable property Alignment of integer type. Now I have extended and updated this class, whereby a new property Position was added, whose type is another class that also has several serializable properties. The new property Position is now supposed to take on the role of old Alignment property, that is since type of Position property is another class, one of its members would contain the value that was previously contained in Alignment property, thus making Alignment prope开发者_StackOverflowrty obsolete.

What I am trying to figure out is how do I make sure that when I deserialize the old version of this class (without Position property in it), I make sure that the deserializer would take the value of Alignment property from the old class and set it as a value of one of the members of Position property in the new class?

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

Sorry the code is in VB, but it applies equally well to C# and any other .NET language.

Can you help me, please?


You can use the XMLSerializer events to help you out:

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

The code would look like:

    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);

Each event has the appropriate event args with very detailed information on the node/attrib/element in question, so more than enough for you to determine what to do.


If your class implements IXmlSerializable you can achieve what you want since you will now have total control on how your class is serialized and deserialized. This will allow you to handle objects serialized before the new Position property, however, implementing IXmlSerializable is a PITA because it's an all or nothing approach.


You can keep the Alignment property around and have it act as an alias to the Position property. If you mark it with [ObsoleteAttribute], this will warn users of your class that the property is obsolete and should no longer be used. At some point, you might be able to drop support for the obsolete property entirely. This resolves both serialization and public interface compatibility concerns.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜