protobuf-net 中通用集合的序列化

Posted

技术标签:

【中文标题】protobuf-net 中通用集合的序列化【英文标题】:Serialization of generic collections in protobuf-net 【发布时间】:2014-03-27 09:16:22 【问题描述】:

我正在尝试使用 protobuf-net 序列化字典,但仍然得到“意外的子类型:”通用列表异常。

这就是我构建字典的方式:

        var list = new List<DummyObject1>();
        list.Add(new DummyObject1());

        var dict = new Dictionary<string, object>();
        dict["0"] = new DummyObject1();
        dict["1"] = new DummyObject1();
        dict["2"] = list;

我将类型添加到默认模型中

        model.Add(typeof(object), true);
        model.Add(typeof (DummyObject1), true);

对于这种情况有什么解决方案或解决方法吗?

编辑:我用这样的解决方法让它工作;

首先我为 List 写了一个包装类

        public class ListWrapper
        
            public List<object> Items  get; set; 
        

我注册了类型和项目字段

        ProtoBuf.Meta.RuntimeTypeModel.Default.Add(typeof(ListWrapper));
        ProtoBuf.Meta.RuntimeTypeModel.Default[typeof(ListWrapper)].AddField(1, "Items");

现在我可以序列化和反序列化字典

        var dict = new Dictionary<string, object>();
        dict["0"] = new DummyObject1();
        var lw = new ListWrapper  Items = new List<object>  new DummyObject1()  ;
        dict["2"] = lw;


        using (var stream = new MemoryStream())
        
            Serializer.Serialize(stream, dict);
            stream.Seek(0, SeekOrigin.Begin);
            var req = Serializer.Deserialize<Dictionary<string, object>>(stream);
        

【问题讨论】:

【参考方案1】:

很简单,protobuf-net 不能很好地与object 配合使用,并且总是会与(例如)Dictionary&lt;string,object&gt; 配合使用。这不是一个受支持的用例,因为 google protobuf 规范期望数据遵循一个端到端的合同。对于一些继承场景,我可以欺骗它,但object 太模糊了

【讨论】:

感谢您的回复。我使用了包装类 ListWrapper 而不是 List 并且我摆脱了异常,但现在我无法反序列化由 ListWrapper 类包装的列表。我可以解决这个问题吗? @ocozalp 很难在没有看到 ListWrapper&lt;T&gt; 的情况下发表评论;p 公共类 ListWrapper public List Items get;放; :)) @ocozalp 好吧,它仍在使用object,所以它仍然无法工作 - 另外,除非您添加一些字段标记(或在代码中配置它),否则有 没有什么可以序列化的 - 需要一些[ProtoMember(1)] 或类似的 这让我很难过。 :( 我正在使用 apache openNLP 的端口。我开始使用 IKVM 但模型加载时间很糟糕,即使在直接 C# 端口中也没有更好的方法。猜猜这只是库的构建方式。无论如何我开始插入在 protobuf-net 中解决这个问题,但我从序列化程序得到不完整的输出.读完之后,我现在得出的结论是代码中使用的从原始库继承的泛型。

以上是关于protobuf-net 中通用集合的序列化的主要内容,如果未能解决你的问题,请参考以下文章

ProtoBuf-net 序列化 IEnumerable<T>

用 Protobuf-net 替换 binaryformatter

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

手工使用Protobuf-net工具来序列化对象

protobuf-net 如何序列化 DateTime?

Protobuf-net - 啥被序列化了?