2013-02-10 28 views
5

Używam protobuf-net (wersja 2.0.0.621) i mam problem z serializacją Typ listy, gdzie T jest moją własną klasą (nie ma znaczenia, co zawiera) i zastępczym jest ustawiony na T.Lista serializacji <T> przy użyciu surogatu z wyjątkiem protobuf-net

surogat jest ustawiony tak:

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

MojaKlasa:

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

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

Potem stworzyć ogólny wykaz dodatków typu myClass tance, wypełnić go z pozycji i szeregować je tak:

ProtoBuf.Serializer.Serialize(stream, list); 

Problem występuje na deserializacji, ciśgle „null” w zastępstwie w niejawnej konwersji operatora:

static public implicit operator MyClassSurrogate(MyClass myClass) 

następnie „myClass "ma wartość zerową.

Jeśli usuniemy surogat i ozdobię MyClass z atrybutami proto, wszystko będzie działać poprawnie.

Czy możesz mi powiedzieć, co robię źle?

Dzięki.

+0

zignoruj ​​komentarz, jeśli jest bezużyteczny, po prostu próbuję pomóc, ale nigdy nie użyłem buforów protokołu. W każdym razie pytanie wydaje się dość proste, czy to wskazuje na właściwy kierunek? http://stackoverflow.com/questions/6498438/protobuf-net-cannot-serialize-type-data-how-can-i-define-type-data-with-protoc – bas

Odpowiedz

5

Dodawanie pustego czek na niejawna konwersja operatora wydaje się rozwiązać problem, tj:

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

Operator niejawna jest początkowo zwany kiedyś o zerowej wartości na deserializacji z wynikiem pojawiających się być ignorowane.

Pełne wdrożenie 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 }; 
    } 
} 

Pełna serializacji/deserializacji przykład:

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

Wartość zerowa jest używany dość często, także podczas deserializacji. Powinieneś być w stanie rozwiązać ten problem po prostu mówiąc operator konwersji tłumaczyć null jako wartość null:

if(value == null) return null; 

Myśląc o nim, mogę prawdopodobnie bezpiecznie dodać „jeśli oba typy referencyjne, tłumaczyć null jako wartość null automatycznie”.