protobuf的和列表的 - 如何序列化/反序列?

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

  •  06-09-2019
  •  | 
  •  

我有不同类型,如整数,字符串,和自定义类型在它的对象的List<object>。所有的自定义类型的protobuf调整。 我想现在要做的是序列化/反序列化这个名单与protobuf.net。到现在为止,我怀疑我有每个类型明确声明,这是不幸的是不可能的这些混合列表结构。因为二进制格式化器没有问题,做这些事情,我希望我错过了一些东西,你能帮助我。 所以我的问题是如何应对protobuf.net对象。

有帮助吗?

解决方案

(公开:我protobuf网的作者)

BinaryFormatter是基于元数据的串行化器;即,它发送关于序列中的每个对象的.NET类型信息。 protobuf网是基于合同的串行器(XmlSerializer / DataContractSerializer的二进制等效值,这也将拒绝此)。

有用于运送的任意的对象,因为另一端会有的没有办法的知道您要发送什么没有电流机制;但是,如果你有一个的组已知不同的的对象,你要发送的类型,有可能的选择。还有在流水线工作,以允许在运行时可扩展架构(而不仅仅是属性,它是固定在编译) - 但这还远远没有完成。


这是不理想,但它的工作原理......当我已经完成了支持运行时模式的工作应该比较容易:

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

其他提示

List<YourClass> list;
ProtoBuf.Serializer.Deserialize<List<YourClass>>(filestream);
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top