Protobuf-net:嵌套的 IEnumerable 对象

Posted

技术标签:

【中文标题】Protobuf-net:嵌套的 IEnumerable 对象【英文标题】:Protobuf-net : Nested IEnumerable objects 【发布时间】:2013-05-09 10:05:47 【问题描述】:

我正在使用 Protobuf-net 序列化自定义嵌套列表。我知道本机列表不能直接嵌套,这就是为什么我使用容器对象作为内部列表的原因。但是,我也想让我的容器对象 IEnumerable 但这意味着 Protobuf-net 会抛出错误:

不支持嵌套或锯齿状列表和数组

这是导致错误的列表结构示例:

[ProtoContract]
public class MyOuterList<T>

    [ProtoMember(1)]
    readonly List<MyInnerList<T>> nestedData = new List<ObjectList<T>>();


[ProtoContract]
public class MyInnerList<T> : IEnumerable<T>

    [ProtoMember(1)]
    private readonly List<T> data = new List<T>();

解决方法是从MyInnerList 中删除 IEnumerable,但显然这会阻止它直接可迭代。是否可以使用像 [ProtobufCustomObjectSoPleaseIgnoreIEnumerable] 这样的鬼鬼祟祟的属性?

到目前为止,我想出的最佳替代方法是使用 Enumerable 属性,如下所示,但我担心该属性仍可能再次被转换回列表。我更愿意以某种方式使用GetEnumerator/yield,但我不知道如何使用。

[ProtoContract]
public class MyInnerList<T>

    [ProtoMember(1)]
    private readonly List<T> data = new List<T>();

    public IEnumerable<T> Data
    
        get  return this.data; 
    

【问题讨论】:

【参考方案1】:

有没有像[ProtobufCustomObjectSoPleaseIgnoreIEnumerable] 这样的偷偷摸摸的属性可以使用?

是的:

[ProtoContract(IgnoreListHandling=true)]
public class MyInnerList<T> : IEnumerable<T>

    [ProtoMember(1)]
    private readonly List<T> data = new List<T>();

偷偷摸摸是偷偷摸摸的。 IgnoreListHandling 有智能感知文档:

如果指定,不要将此类型视为列表,即使它看起来像一个。

另外,由于like this one 的多个请求,我计划尽快实现对锯齿状数组/列表的支持。计划基本上是让运行时在序列化程序的想象中用一个成员(字段 1)欺骗包装器,所以你可以使用List&lt;List&lt;T&gt;&gt;,它会像你上面的模型一样工作(它甚至是有线兼容的,因为你明智地选择了字段1)。

【讨论】:

完美,非常感谢。我不知道该去哪里找。 仍然无法使其正常工作。问题发布在这里:code.google.com/p/protobuf-net/issues/… @shakinfree k;会看看 有没有办法将它注入到从 .proto 文件生成的类中?我有一个部分类扩展片段,它将 IEnumerable 添加到这样的类中,但我无法在其中添加 ProtoContract,因为它已经存在于生成的代码中。 @Miral 不是通过属性,但您可以使用 var metaType = RuntimeTypeModel.Add(type, false) 然后配置 metaType...

以上是关于Protobuf-net:嵌套的 IEnumerable 对象的主要内容,如果未能解决你的问题,请参考以下文章

ProtoBuf-Net 错误消息 - “不支持嵌套或锯齿状列表和数组”

Protobuf-net:如何调试“不支持嵌套或锯齿状列表和数组”

如何使用 protobuf-net 序列化/反序列化锯齿状/嵌套数组?

Protobuf-net 使用嵌套数据反序列化时出现无效的线型异常(C++ 到 C#)

如何使用 protobuf 序列化大型嵌套数组?

protobuf-net:日期时间的编码