2013-10-31 39 views
6

假如我有这个类:从旧版本的对象的反序列化对象的新版本

[Serializable] 
public class SomeClass 
{ 
    public SomeClass() {//init} 
    public string SomeString {get;set;} 
} 

在应用程序关闭时,这个类被序列化和反序列化得到的下一次运行。

然后,我建立并发布了应用程序,现在类已更改:

[Serializable] 
public class SomeClass 
{ 
    public SomeClass() {//init} 
    public string SomeString {get;set;} 
    public int SomeInt {get;set;} 
} 

有没有一种方法来设置属性其默认值的情况下,反序列化它不是在旧序列中发现目的?

我想过的一种方式是保留旧版本的类,然后检查已序列化的版本,然后循环旧对象的属性并将它们设置在新对象中,但这对我来说是无意义的,任何其他有意义的解决方案?

+0

什么串行器?有些接口/属性可用于修改对象[de]序列化的方式,但取决于哪个库。 –

+0

@BradChristie我使用'BinaryFormatter' – FPGA

+1

看一看使用自定义[胶粘剂](http://msdn.microsoft.com/en-us/library/system.runtime.serialization.formatters.binary.binaryformatter.binder (v = vs.110)的.aspx) –

回答

4

您可以用属性

[OptionalField()] 

Version Tolerant Serialization

然后,该类会是什么样子作为解释标记领域这个:

[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; 
    } 
} 
+0

但有没有办法指定默认值的测试样品,不'[OnDeserialized()]',对不对?我试着通过设置后台字段值,但它给了0而不是10,但与'[OnDeserialized()]' – FPGA

+1

正常工作据我所知只有一种方式。你可以实现[ISerializable接口](http://msdn.microsoft.com/en-US/library/System.Runtime.Serialization.ISerializable%28v=vs.110%29。aspx),它强制你实现方法GetObjectData(在序列化过程中使用),还需要实现一个附加的构造函数,它带有两个参数(SerializationInfo info,StreamingContext context),这些参数将在反序列化过程中使用。在那里,你也可以设置你的领域/财产的价值,但在我看来这是相当复杂的。 –

+0

我会坚持这一个,它的完美谢谢 – FPGA

2

什么,我会做的是基础在哪里领域具有默认值的字段的SomeInt。 IE浏览器。

public class SomeClass 
{ 
    public SomeClass() { } 

    int someInt = 10; 

    public string SomeString { get; set; } 
    public int SomeInt 
    { 
     get { return someInt; } 
     set { someInt = value; } 
    } 
} 

然后,如果没有提供SomeInt值,串行器反序列化对象时默认值仍然设置。

编辑:更新

添加使用XML序列化的样本应用程序。现在来切换类类型简单地取消对#define serialize声明中排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 
} 
+0

让我试,我不认为它的那样简单 – FPGA

+0

它没有反序列化,但someInt值为0,而不是10! – FPGA

+0

我尝试了利用多种类型,什么反序列化后,我得到的是该类型的默认值,而不是在场上 – FPGA