2013-02-10 4 views
5

Ich benutze Protobuf-net (Version 2.0.0.621) und ein Problem Serialisierung List Typ wo T ist meine eigene Klasse (es ist egal, was es enthält) und ein Surrogat für T. gesetztSerialisierung Liste <T> mit einem Ersatz mit Protobuf-Net Ausnahme

der Ersatz wird wie folgt aus:

ProtoBuf.Meta.RuntimeTypeModel.Default.Add(typeof(MyClass), false).SetSurrogate(typeof(MyClassSurrogate)); 

MyClass:

public class MyClass 
{ 
    public int Number { get; set; } 
} 

[ProtoContract] 
MyClassSurrogate 
{ 
    [ProtoMember(1)] 
    public int Number { get; set; } 
} 

Dann erstelle ich eine generische Liste von Typ MyClass ins tung, füllen Sie es mit Gegenständen und es so serialisiert werden:

ProtoBuf.Serializer.Serialize(stream, list); 

Das Problem auf Deserialisierung auftritt, halte ich in dem impliziten Operator conversion "null" in dem Leihmutter bekommen:

static public implicit operator MyClassSurrogate(MyClass myClass) 

dann ‚myClass ' ist Null.

Wenn ich das Ersatzzeichen entferne und MyClass mit den Proto-Attributen dekoriere, funktioniert alles gut.

Können Sie mir sagen, was ich falsch mache?

Danke.

+0

Kommentar ignorieren, wenn nutzlos, nur versuchen zu helfen, aber ich habe nie Protokollpuffer verwendet. Wie auch immer, die Frage scheint ziemlich einfach zu sein, weist das auf die richtige Richtung hin? http://stackoverflow.com/questions/6498438/protobuf-net-cannot-serialize-type-data-how-can-i-define-type-data-with-protoc – bas

Antwort

5

einen Null-Schecks an die impliziten Operator Umwandlung Hinzufügen scheint das Problem zu beheben, das heißt:

public static implicit operator MyClassSurrogate(MyClass myClass) 
{ 
    return myClass != null ? new MyClassSurrogate { Number = myClass.Number } : null; 
} 

Der implizite Operator zunächst einmal mit einem Nullwert auf Deserialisierung mit dem Ergebnis genannt wird erscheinen ignoriert werden.

Vollständige Umsetzung der MyClassSurrogate:

[ProtoContract] 
public class MyClassSurrogate 
{ 
    [ProtoMember(1)] 
    public int Number { get; set; } 

    public static implicit operator MyClassSurrogate(MyClass myClass) 
    { 
     return 
      myClass != null 
      ? new MyClassSurrogate { Number = myClass.Number } 
      : null; 
    } 

    public static implicit operator MyClass(MyClassSurrogate myClass) 
    { 
     return new MyClass { Number = myClass.Number }; 
    } 
} 

Voll Serialisierung/Deserialisierung Beispiel:

var model = ProtoBuf.Meta.RuntimeTypeModel.Default; 
model.Add(typeof(MyClassSurrogate), true); 
model.Add(typeof(MyClass), false).SetSurrogate(typeof(MyClassSurrogate)); 
var stream = new System.IO.MemoryStream(); 
var list = new List<MyClass>(); 
for (int x = 0; x < 10; x++) list.Add(new MyClass { Number = x });    
ProtoBuf.Serializer.Serialize(stream, list); 
stream.Seek(0, SeekOrigin.Begin); 
var xs = ProtoBuf.Serializer.Deserialize<List<MyClass>>(stream); 
foreach (var x in xs) Debug.WriteLine(x.Number); 
1

Der Wert null ist ziemlich häufig verwendet, während der Deserialisierung einschließlich. Sie sollten diese in der Lage sein, einfach zu beheben, indem Sie den Konvertierungsoperator zu sagen als null zu übersetzen null:

if(value == null) return null; 

Denken Sie darüber nach, kann ich wohl sicher hinzufügen ein „wenn beiden Referenztypen sind, als null automatisch null übersetzen“.