Pregunta

tengo un List<object> con diferentes tipos de objetos, como números enteros, cadenas y tipos personalizados.Todos los tipos personalizados están ajustados por protobuf.Lo que quiero hacer ahora es serializar/deserializar esta lista con protobuf.net.Hasta ahora sospecho que tengo que declarar todos y cada uno de los tipos explícitamente, lo que lamentablemente no es posible con estas construcciones de listas mixtas.Debido a que el formateador binario no tiene problemas para hacer estas cosas, espero haberme perdido algo y que puedan ayudarme.Entonces mi pregunta es cómo lidiar con objetos en protobuf.net.

¿Fue útil?

Solución

(divulgación:Soy el autor de protobuf-net)

BinaryFormatter es un serializador basado en metadatos;es decir.envía información de tipo .NET sobre cada objeto serializado.protobuf-net es un serializador basado en contratos (el equivalente binario de XmlSerializer / DataContractSerializer, que también lo rechazará).

Actualmente no existe ningún mecanismo para transportar arbitrario objetos, ya que el otro extremo tendrá de ninguna manera de saber lo que estás enviando;sin embargo, si tienes un conjunto conocido de diferente tipos de objetos que desea enviar, puede haber opciones.También hay trabajo en proceso para permitir esquemas extensibles en tiempo de ejecución (en lugar de solo atributos, que se fijan en la compilación), pero esto está lejos de estar completo.


Esto no es ideal, pero funciona...Debería ser más fácil cuando haya completado el trabajo para admitir esquemas de tiempo de ejecución:

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

Otros consejos

List<YourClass> list;
ProtoBuf.Serializer.Deserialize<List<YourClass>>(filestream);
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top