protobuf und List - wie serialisiert / deserialisiert?

StackOverflow https://stackoverflow.com/questions/923977

  •  06-09-2019
  •  | 
  •  

Frage

Ich habe eine List<object> mit verschiedenen Arten von Objekten in es wie ganze Zahlen, Strings und benutzerdefinierte Typen. Alle benutzerdefinierten Typen sind protobuf bereinigt. Was ich tun möchte, ist jetzt zu serialisiert / deserialisiert diese Liste mit protobuf.net. Bis jetzt habe ich den Verdacht, dass ich jeden und jede Art ausdrücklich zu erklären haben, die mit diesen gemischten Liste Konstrukte leider nicht möglich ist. Da die binären formater keine Probleme haben, diese Dinge zu tun, ich hoffe, dass ich etwas verpaßt, und dass Sie mir helfen können, aus. Also meine Frage ist, wie man mit Objekten in protobuf.net befassen.

War es hilfreich?

Lösung

(Offenlegung: Ich bin der Autor von protobuf-net)

BinaryFormatter ist ein Metadaten-basierte Serializer; das heißt, es sendet .NET-Typ Informationen zu jedem Objekt serialisiert. protobuf-net ist eine vertragsbasierte Serializer (das binäre Äquivalent von XmlSerializer / DataContractSerializer, die auch diese ablehnen).

Es gibt keinen aktuellen Mechanismus für den Transport von beliebigen Objekten, da das andere Ende wird keine Möglichkeit zu wissen, was Sie senden; Wenn Sie jedoch einen bekannter Satz haben von andere Objekttypen Sie senden möchten, kann es Optionen. Es wird auch in der Pipeline arbeitet Runtime-erweiterbaren Schemata zu ermöglichen (und nicht nur Attribute, die bei der Erstellung festgelegt sind.) - aber das ist noch lange nicht abgeschlossen


Das ist nicht ideal, aber es funktioniert ... es soll einfacher sein, wenn ich die Arbeit abgeschlossen hat Runtime-Schema zu unterstützen:

using System;
using System.Collections.Generic;
using ProtoBuf;
[ProtoContract]
[ProtoInclude(10, typeof(DataItem<int>))]
[ProtoInclude(11, typeof(DataItem<string>))]
[ProtoInclude(12, typeof(DataItem<DateTime>))]
[ProtoInclude(13, typeof(DataItem<Foo>))]
abstract class DataItem {
    public static DataItem<T> Create<T>(T value) {
        return new DataItem<T>(value);
    }
    public object Value {
        get { return ValueImpl; }
        set { ValueImpl = value; }
    }
    protected abstract object ValueImpl {get;set;}
    protected DataItem() { }
}
[ProtoContract]
sealed class DataItem<T> : DataItem {
    public DataItem() { }
    public DataItem(T value) { Value = value; }
    [ProtoMember(1)]
    public new T Value { get; set; }
    protected override object ValueImpl {
        get { return Value; }
        set { Value = (T)value; }
    }
}
[ProtoContract]
public class Foo {
    [ProtoMember(1)]
    public string Bar { get; set; }
    public override string ToString() {
        return "Foo with Bar=" + Bar;
    }
}
static class Program {
    static void Main() {
        var items = new List<DataItem>();
        items.Add(DataItem.Create(12345));
        items.Add(DataItem.Create(DateTime.Today));
        items.Add(DataItem.Create("abcde"));
        items.Add(DataItem.Create(new Foo { Bar = "Marc" }));
        items.Add(DataItem.Create(67890));

        // serialize and deserialize
        var clone = Serializer.DeepClone(items);
        foreach (DataItem item in clone) {
            Console.WriteLine(item.Value);
        }
    }
}

Andere Tipps

List<YourClass> list;
ProtoBuf.Serializer.Deserialize<List<YourClass>>(filestream);
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top