protobuf 和 List<object> - 如何序列化/反序列化?

Posted

技术标签:

【中文标题】protobuf 和 List<object> - 如何序列化/反序列化?【英文标题】:protobuf and List<object> - how to serialize / deserialize? 【发布时间】:2009-05-29 01:14:47 【问题描述】:

我有一个List&lt;object&gt;,其中包含不同类型的对象,例如整数、字符串和自定义类型。所有自定义类型都经过 protobuf 调整。 我现在想做的是用 protobuf.net 序列化/反序列化这个列表。到目前为止,我怀疑我必须显式声明每种类型,不幸的是,这些混合列表构造不可能做到这一点。因为二进制格式化程序在做这些事情时没有问题,我希望我错过了一些东西,你可以帮助我。 所以我的问题是如何处理 protobuf.net 中的对象。

【问题讨论】:

还请告诉我,以序列化具有超过 10,000 个元素的列表为例,将消耗多少数据? 【参考方案1】:

(披露:我是protobuf-net的作者)

BinaryFormatter 是一个基于元数据的序列化器;即它发送关于每个序列化对象的 .NET 类型信息。 protobuf-net 是一个基于合约的序列化程序(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);
        
    

【讨论】:

感谢 Gravell,实际上我真的很喜欢您的工作,并希望直接从您那里得到答复。我知道列表中有哪些数据类型,所以我真的很好奇您的解决方案。 感谢 Gravell,您能否估计一下您何时完成对运行时模式的支持? 我不想;我之前给出了一个估计,但它不适合......有很多边缘情况需要适应,即使是我优化它之前。如果我不得不猜测,我估计除非我有足够的空闲时间(我没想到),否则还需要几个月的时间。我还试图通过最新的有线格式更改来使“主干”保持最新状态,这让事情变得更加有趣。【参考方案2】:
List<YourClass> list;
ProtoBuf.Serializer.Deserialize<List<YourClass>>(filestream);

【讨论】:

那是额外的&gt;吗?

以上是关于protobuf 和 List<object> - 如何序列化/反序列化?的主要内容,如果未能解决你的问题,请参考以下文章

使用 protobuf-net 序列化 List<IComparable> 成员

为啥我的 List<Foo> 不能用 protobuf-net 序列化?

使用带有 protobuf-net 异常的代理对 List<T> 进行序列化

使用 Protobuf-net,我得到一个关于 List<Subclassable> 的未知线路类型的异常

Protobuf 继承和泛型

protobuf-net 可以用来(反)序列化包含异构对象的列表吗?