2012-10-20 2 views
21

Mi dispiace se questo è un duplicato. Ho cercato più punti per una risposta che io possa capire tra cui:Come serializzare la classe ereditata con ProtoBuf-Net

ProtoBuf.net Base class properties is not included when serializing derived class

Serialize inherited classes using protobuf-net

Le mie scuse, ma non ho davvero capire le risposte. Sto cercando un serializzatore binario più veloce e compatto e ProtoBuf sembra che potrebbe essere la risposta. Ho bisogno di serializzare un set di classi che derivano tutte da una singola classe base. Ci sono un gran numero di essi quindi prima di impegnarsi a modificare il codice di classe ho eseguito un semplice test. Inoltre, non desidero modificare le classi in alcun modo che possa avere un impatto sulla deserializzazione dei vecchi file persistenti generati con il serializzatore binario NET.

Questa è la classe base:

[ProtoContract] 
    public class BaseClass 
    { 
     [ProtoMember(1)] 
     public string Name 
     { 
      get; set; 
     } 
     [ProtoMember(2)] 
     public int Age 
     { 
      get; set; 
     } 
    } 

Questa è la classe derivata:

[ProtoContract] 
    public class SubClass1 : BaseClass 
    { 
     [ProtoMember(3)] 
     public string Town 
     { 
      get; set; 
     } 

     [ProtoMember(4)] 
     public Sex Sex 
     { 
      get; set; 
     } 
    } 

Questo è il codice per serializzare e deserializzare (presa direttamente dalla Guida introduttiva

var person = new SubClass1 { Age = 25, Name = "Fred", Town = "Denbigh", Sex = Sex.Female }; 

      using (var file = File.Create(filename)) 
      { 
       Serializer.Serialize(file, person); 
      } 

e deserializzare:

SubClass1 newPerson; 
      using (var file = File.OpenRead(filename)) 
      { 
       newPerson = Serializer.Deserialize<SubClass1>(file); 
      } 

      MessageBox.Show(newPerson.Name + 
       " : " + newPerson.Town + 
       " : " + newPerson.Age.ToString() + 
       " : " + newPerson.Sex); 

Il risultato è ": Denbigh: 0: Female"

In qualche modo i valori delle proprietà della classe di base non vengono serializzati? Inizialmente l'ho testato con gli indici di ProtoMember per la classe derivata come 1, 2. Non pensavo che funzionasse così per il 3, 4. Sembra non fare alcuna differenza. Nella mia paranoia ho eseguito lo stesso test utilizzando il serializzatore binario standard NET e ottenuto il risultato previsto: "Fred: Denbigh: 25: Female"

Cosa mi manca, per favore?

risposta

21

È necessario utilizzare l'attributo ProtoInclude sulla classe di base:

[ProtoContract] 
[ProtoInclude(500, typeof(SubClass1))] 
public class BaseClass 
{ 

ARG id (500 nell'esempio di cui sopra) dovrebbe essere unico per quella classe. Vedere l'articolo this per ulteriori informazioni

+0

ringrazio molto - così semplice – ScruffyDuck

+1

mi fa risparmiare un po 'di battitura, ta –

+0

link sembra essere rotto ... – RenniePet

1

So che è piuttosto vecchio, ma può aiutare qualcuno. In alcuni casi è possibile risolvere il problema ridefinendo proprietà di base nel sottotipo:

[ProtoContract] 
public class SubClass1 : BaseClass 
{ 
    [ProtoMember(1)] 
    public string BaseName 
    { 
     get{return base.Name;} 
     set{base.Name = value;} 
    } 

    ... 

    [ProtoMember(3)] 
    public string Town 
    { 
     get; set; 
    } 

    [ProtoMember(4)] 
    public Sex Sex 
    { 
     get; set; 
    } 
} 
+0

Non penso che funzionerà perché "Sottoclass1" avrà due proprietà definite come "ProtoMember" con index = 1 ('Name' e' BaseName') – BaltoStar