【问题标题】:Inherited class protobuf-net serialization继承类protobuf-net序列化
【发布时间】:2012-12-01 17:21:57
【问题描述】:

继承的类C2流序列化后是这样的:

0x5a 0x03

0x08 0x97 0x01

0x08 0x96 0x01

我不明白那是第一组字节(5a 03)?我相信它必须是第二和第三,它们代表 Z1 和 Z2 值?

我的代码:

    [ProtoContract]
    class C1
    {
        [ProtoMember(1, DataFormat = DataFormat.Default)]
        public int Z1 { get; set; }
    }

    [ProtoContract]
    class C2 : C1
    {
        [ProtoMember(1, DataFormat = DataFormat.Default)]
        public int Z2 { get; set; }
    }      

    public static void Main()
    {
        MemoryStream stream = new MemoryStream();
        ProtoBuf.Meta.RuntimeTypeModel.Default.Add(typeof(C1), true).AddSubType(11, typeof(C2));
        C2 c2 = new C2() {Z1 = 150, Z2 = 151};           
        Serializer.Serialize(stream, c2);
    }

【问题讨论】:

    标签: protobuf-net


    【解决方案1】:
    • 0x5a = 字段编号 11,线路类型 2(长度前缀) - 这表示通过将子类封装为内部消息进行继承
    • 0x03 = 3(有效负载长度)
      • 0x08 = 字段 1,线型 0(变体)
      • 0x97 0x01 = 151(varint = little-endian 使用 MSB 作为延续)
    • 0x08 = 字段编号 1,线型 0(变体)
      • 0x96 0x01 = 150

    基本上映射到(在.proto中)

    message C1 {
        optional int32 Z1 = 1;
        optional C2 c2 = 11;
    }
    message C2 {
        optional int32 Z2 = 1;
    }
    

    【讨论】:

    • 您在另一个线程中写道(如果我没记错的话)继承不是 protobuf 规范的一部分。那么为什么序列化看起来像那样(在数据包前进行封装)?任何消除这种情况的方法,所以它会是这样的: [code]message C1 { optional int32 Z1 = 1; } 消息 C2 { 可选 int32 Z2 = 1; }[/code]
    • @GromHellscream 确实,继承不是 protobuf 规范的一部分;为了方便起见,protobuf-net 使用封装提供了一个实现。序列化不是“在”数据包“前面” - 整个事情是一个单一的 protobuf 消息,可在任何平台上使用。你提出的“那样的东西”没有意义:两者都不包括另一个。这里的整个问题是,在谈论继承时,您需要能够发送 either - 这样您就可以发送 just C1(而不是 C2 sub -class),或者是C1C2 的新C3 子类。 protobuf-net 可以处理。如果你...
    • @GromHellscream ...想要完全展平您的模型(失去替代支持),那么也可以这样做,但您基本上会得到类似 message C2 { Z1 = 1; Z2 = 2; } 的东西 - 您可以这样做这很容易,但是:那么它并不真正支持该词的通常含义的继承。
    • 在我的情况下,我不需要序列化数据包内的替换支持和继承数据,因为两端(客户端和服务器)在其两侧都有所有类型层次结构描述。实际上,服务器端是嵌入式设备,使用纯 c++ protobuf,不支持 protobuf-net 继承约定(是的,我可以实现它,但这将是无用的性能开销)。类型层次表示特定领域的高级实体,因此使用嵌套属性或一级层次类非常不方便。
    • 如果我不更改 RuntimeTypeModel(或明确定义此行为),为什么 protobuf-net 不能简单地从所有基类中收集所有标有 ProtoMember 属性的属性?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-11-16
    • 1970-01-01
    • 2012-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-09
    相关资源
    最近更新 更多