protobuf et liste - comment sérialiser / désérialiser?

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

  •  06-09-2019
  •  | 
  •  

Question

J'ai un List<object> avec différents types d'objets qu'il contient comme des entiers, des chaînes et des types personnalisés. Tous les types personnalisés sont ajustés Protobuf. Ce que je veux faire maintenant est de linéariser / désérialiser cette liste avec protobuf.net. Jusqu'à présent, je suppose que je dois déclarer chaque type et chaque explicitement, ce qui est malheureusement pas possible avec ces constructions-liste mixte. Parce que le binaire n'a pas formater des problèmes à faire ces choses, je l'espère que je manqué quelque chose et que vous pouvez me aider. Donc, ma question est de savoir comment traiter les objets protobuf.net.

Était-ce utile?

La solution

(divulgation: Je suis l'auteur de protobuf-net)

BinaryFormatter est un sérialiseur à base de méta-données; à-dire qu'il envoie des informations de type .NET à propos de chaque objet sérialisé. protobuf-net est un sérialiseur contractuelle (l'équivalent binaire de XmlSerializer / DataContractSerializer, qui rejette également ce sujet).

Il n'y a pas de mécanisme actuel pour le transport arbitraires objets, depuis l'autre extrémité aura aucun moyen de savoir ce que vous envoyez; Cependant, si vous avez un ensemble connu de différents types d'objets que vous souhaitez envoyer, il peut y avoir des options. Des travaux sont également en cours pour permettre des schémas d'exécution extensible (plutôt que les attributs justes, qui sont fixés à la construction) -. Mais cela est loin d'être complète


Ce n'est pas idéal, mais il fonctionne ... il devrait être plus facile quand j'ai terminé le travail pour soutenir les schémas d'exécution:

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);
        }
    }
}

Autres conseils

List<YourClass> list;
ProtoBuf.Serializer.Deserialize<List<YourClass>>(filestream);
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top