protobuf-net序列化对象图

jz8*_*z87 17 protocol-buffers protobuf-net

如果我有对象A和B都包含一些字段序列化字段F,并且都指向相同的可序列化对象C. protobuf-net是通过引用序列化还是按值序列化?当反序列化对象图时,protobuf-net是否会为AF和BF生成2个单独的对象?我问,因为我想知道序列化是否保留了引用相等性.

Mar*_*ell 19

由Google定义的原始"protobuf"规范是树序列化器(如XmlSerializer).所以默认情况下,你会反序列化两次C序列化和两个不同的对象.

然而,这是一个常见的问题,在"v2"中,我将此作为选择加入行为; 请注意,您应该只将它用于protobuf-net到protobuf-net,因为其他客户端不会期望这种配置(尽管它仍然是一个有效的protobuf流).

例如(使用属性,位也可以使用运行时模型):

[ProtoContract]
public class A {
    ...
    [ProtoMember(5, AsReference=true)]
    public C Foo {get;set;}
}

[ProtoContract]
public class B {
    ...
    [ProtoMember(7, AsReference=true)]
    public C Bar {get;set;}
}

[ProtoContract]
public class C {...}
Run Code Online (Sandbox Code Playgroud)

这将序列化一次实例,在输出中生成唯一的id.反序列化时,两个地方都将使用相同的对象.

  • 哇,老实说,我没想到会有引用功能,因为考虑到 PB 的最初目的,我认为底层格式可能不支持它。这真是太棒了。 (2认同)
  • 正如后续问题一样,如果我通过引用序列化数组,该数组的每个元素是否也通过引用序列化,或者只是顶级数组本身? (2认同)
  • 看起来当前的protobuf-net v2修订版445仅支持类(或数组元素)引用相等.当序列化两个引用相等的集合时,在反序列化后,您将获得两个不同的引用相等意义集合,但这些集合的所有元素将是引用相等的. (2认同)