How can I override deserialization in C#

怎甘沉沦 提交于 2019-12-23 10:50:38

问题


I've got a class that will undergo certain version changes over the course of time. The data from inside this class is serialized and deserialized as part of the startup of my application. The problem I have is if I update the class by adding more properties, and then start the application, the old data does not get loaded properly.
What I'm looking to do is override the deserialization step, I don't mind manually reconstructing the object from xml, as I have a version number stored and can use it to recursively update versions of the object.

Is there an interface I can implement, or an attribute I can set somewhere, to be able to do this?

If you can't think of a way to do what I want, are there alternatives? such as defaulting values for properties that may not exist in the version of the xml I am loading.


回答1:


Typically for versioning, you can use the OptionalField attribute to newly added members that might cause compatibility problems. During serialization, if member was not serialized, this leaves members value as null rather than throwing the exception.

Also, take a look at IDeserializationCallback.OnDeserialization interface which allows you to customize your deserialization.




回答2:


Implement the IXmlSerializable interface.




回答3:


If it is xml-serialization specifically you're talking about you should implement the IXmlSerializable interface. If it's binary serialization you could just tag the new members with the OptionalField-attribute.

You can read more here: http://msdn.microsoft.com/en-us/library/ms229752(VS.80).aspx




回答4:


You can implement the ISerializable interface and provide a constructor which takes a SerializationInfo and a StreamingContext object to gain a finegrain control of the serialization/deserialization process.

For example:

[Serializable]
public struct MyStruct: ISerializable
{
    private readonly int _x;
    private readonly int _y;

    // normal constructor
    public MyStruct(int x, int y) : this()
    {
        _x = x;
        _y = y;
    }

    // this constructor is used for deserialization
    public MyStruct(SerializationInfo info, StreamingContext text) : this()
    {
        _x = info.GetInt32("X");
        _y = info.GetInt32("Y");
    }

    public int X { get { return _x; } }
    public int Y { get { return _y; } }

    // this method is called during serialization
    [SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
    public void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        info.AddValue("X", X);
        info.AddValue("Z", Y);
    }
}


来源:https://stackoverflow.com/questions/3480804/how-can-i-override-deserialization-in-c-sharp

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!