2013-10-31 7 views
6

Angenommen, ich diese Klasse hatte: Serialized wirdeine neuere Version eines Objekts von einer älteren Version des Objekts Deserialisieren

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

Diese Klasse, wenn die Anwendung geschlossen wird, und wird auf den nächsten Lauf deserialisiert.

Dann baute ich es und veröffentlichte die Anwendung, und jetzt die Klasse hat sich geändert:

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

Gibt es eine Möglichkeit, eine Eigenschaft auf den Standard auf Deserialisierung zu setzen, falls es nicht in der alten serialisierten gefunden Objekt? Eine Art, wie ich dachte, ist, die alte Version der Klasse beizubehalten, dann die Version zu überprüfen, die serialisiert wurde, Eigenschaften des alten Objekts zu schleifen und sie in dem neuen Objekt zu setzen, aber das ist für mich nicht sinnlos Lösung, die Sinn macht?

+0

Welcher Serialisierer? Es gibt Schnittstellen/Attribute, die Sie verwenden können, um zu modifizieren, wie das Objekt [de] serialisiert, aber es hängt davon ab, welche Bibliothek. –

+0

@BradChristie Ich benutze die 'BinaryFormatter' – FPGA

+1

Werfen Sie einen Blick auf die Verwendung eines benutzerdefinierten [Binder] (http://msdn.microsoft.com/en-us/library/system.runtime.serialization.formatters.binary.binaryformatter.binder (v = vs.110) .aspx) –

Antwort

4

Sie Felder mit dem Attribut markieren

[OptionalField()] 

wie erklärt in Version Tolerant Serialization

Die Klasse würde dann folgendermaßen aussehen dies:

[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

hinzugefügt, aber gibt es keine Möglichkeit, den Standardwert anzugeben, ohne '[OnDeserialized()]', oder? Ich habe versucht, indem Sie den Hintergrundwert, aber es gab 0 statt 10, aber funktionierte gut mit '[OnDeserialized()]' – FPGA

+1

Soweit ich weiß gibt es nur einen anderen Weg. Sie könnten die [ISerializable-Schnittstelle] (http://msdn.microsoft.com/en-US/library/System.Runtime.Serialization.ISerializable%28v=vs.110%29) implementieren.aspx), die die Implementierung der Methode GetObjectData (die im Serialisierungsprozess verwendet wird) erzwingt, und Sie müssen außerdem einen zusätzlichen Konstruktor mit zwei Parametern implementieren (SerializationInfo-Info, StreamingContext-Kontext), der während des Deserialisierungsprozesses verwendet wird. Dort können Sie auch den Wert Ihres Feldes/Grundstücks festlegen, aber meiner Meinung nach ist es ziemlich kompliziert. –

+0

ich bleibe bei diesem, es ist perfekt danke – FPGA

2

Was ich tun würde, ist die SomeInt auf ein Feld basieren, wo das Feld einen Standardwert hat. IE.

public class SomeClass 
{ 
    public SomeClass() { } 

    int someInt = 10; 

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

Wenn das Serializer das Objekt deserialisiert, wenn der SomeInt-Wert nicht angegeben wird, wird der Standardwert weiterhin festgelegt.

EDIT: Update

Added eine Beispielanwendung den XML-Serializer verwenden. Nun einfach den Klassentyp wechseln Kommentar- der #define serialize Anweisung in Zeile 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

lassen Sie mich testen, ich dachte nicht, es ist so einfach wie das – FPGA

+0

es deserialize es, aber einigeInt Wert war 0 statt 10! – FPGA

+0

Ich habe das mit mehreren Typen versucht, und was ich nach der Deserialisierung bekomme, ist der Standardwert des Typs und nicht der, der im Feld – FPGA

Verwandte Themen