问题
Suppose I had this class:
[Serializable]
public class SomeClass
{
public SomeClass() {//init}
public string SomeString {get;set;}
}
This class gets Serialized when the application closes, and gets deserialized on the next run.
Then, I built it and released the application, and now the class has changed:
[Serializable]
public class SomeClass
{
public SomeClass() {//init}
public string SomeString {get;set;}
public int SomeInt {get;set;}
}
Is there a way to set a property to its default on deserialization in case its not found in the old serialized object?
One way I thought about is keeping the old version of the class, then check the version that was serialized then looping properties of the old object and setting them in the new object, but this is non sense to me, any other solution that makes sense?
回答1:
You can mark fields with the attribute
[OptionalField()]
as explained in Version Tolerant Serialization
The class would then look like this:
[Serializable()]
public class SomeClass
{
public SomeClass() {//init}
public string SomeString { get; set; }
[OptionalField(VersionAdded = 2)]
public int SomeInt { get; set; }
[OnDeserialized()]
private void SetValuesOnDeserialized(StreamingContext context)
{
this.SomeInt = 10;
}
}
回答2:
What i would do is base the SomeInt on a field where the field has a default value. IE.
public class SomeClass
{
public SomeClass() { }
int someInt = 10;
public string SomeString { get; set; }
public int SomeInt
{
get { return someInt; }
set { someInt = value; }
}
}
Then when the serializer deserializes the object if the SomeInt value is not provided the default value is still set.
EDIT: Update
Added a sample app using the XML serializer. Now to toggle the class type simply uncomment the #define serialize
statement in row 2.
//uncomment for serialization
//#define serialize
using System;
using System.IO;
using System.Xml.Serialization;
namespace TestSerializer
{
class Program
{
static void Main(string[] args)
{
#if serialize
SomeClass some = new SomeClass();
some.SomeString = "abc";
XmlSerializer serializer = new XmlSerializer(some.GetType());
using (StringWriter writer = new StringWriter())
{
serializer.Serialize(writer, some);
File.WriteAllText("D:\\test.xml", writer.ToString());
}
#else
XmlSerializer serializer = new XmlSerializer(typeof(SomeClass));
using (StringReader reader = new StringReader(File.ReadAllText("D:\\test.xml")))
{
var o = serializer.Deserialize(reader) as SomeClass;
if (o != null)
Console.WriteLine(o.SomeInt);
}
Console.ReadKey();
#endif
}
}
#if serialize
[Serializable]
public class SomeClass
{
public SomeClass() { }
public string SomeString { get; set; }
}
#else
[Serializable]
public class SomeClass
{
public SomeClass() { }
private int someInt = 10;
public string SomeString { get; set; }
public int SomeInt
{
get { return someInt; }
set { someInt = value; }
}
}
#endif
}
来源:https://stackoverflow.com/questions/19718306/deserializing-a-newer-version-of-an-object-from-an-older-version-of-the-object