协议缓冲区是不是支持具有共享引用的对象图的序列化?
Posted
技术标签:
【中文标题】协议缓冲区是不是支持具有共享引用的对象图的序列化?【英文标题】:Does protocol buffers support serialization of object graphs with shared references?协议缓冲区是否支持具有共享引用的对象图的序列化? 【发布时间】:2011-05-19 19:13:49 【问题描述】:请注意以下简单程序(基于 protobuf-net 项目 v1 wiki 中的示例):
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using ProtoBuf;
namespace HelloProtoBuf
[ProtoContract]
class Person
[ProtoMember(1)]
public int Id get; set;
[ProtoMember(2)]
public string Name get; set;
[ProtoMember(3)]
public Address Address get; set;
[ProtoContract]
class Address
[ProtoMember(1)]
public string Line1 get; set;
[ProtoMember(2)]
public string Line2 get; set;
class Program
static void Main(string[] args)
var person = new Person
Id = 12345,
Name = "Fred",
Address = new Address
Line1 = "Flat 1",
Line2 = "The Meadows"
;
var person2 = new Person
Id = 4553,
Name = "Nadya",
Address = person.Address
;
var persons = new List<Person> person, person2 ;
Debug.Assert(ReferenceEquals(persons[0].Address, persons[1].Address));
using (var file = File.Create("persons.bin"))
Serializer.Serialize(file, persons);
List<Person> persons2;
using (var file = File.OpenRead("persons.bin"))
persons2 = Serializer.Deserialize<List<Person>>(file);
Debug.Assert(ReferenceEquals(persons2[0].Address, persons2[1].Address));
第二个断言失败。这是 protobuf-net 实现中的错误,还是协议缓冲区根本不支持具有共享引用的对象图?
谢谢。
【问题讨论】:
【参考方案1】:protocol-buffers itself 不支持这个 - 所以不,这不是一个错误。事实上,XmlSerializer
和 DataContractSerializer
* 会做同样的事情(javascriptSerializer
和 JSON.NET 可能也会这样做)。
但是,这是一个常见的请求,所以 protobuf-net v2 支持(基本上:我作弊)。只需将其更改为:
[ProtoMember(3, AsReference=true)]
public Address Address get; set;
(并使用我在大约 5 分钟内上传的 v2 dll,或从代码构建)
*=caveat:DataContractSerializer
确实支持引用,但前提是您使用特定的构造函数;默认禁用
【讨论】:
是否可以通过命令式模型(RuntimeTypeModel)传达这些信息?问题是我的代理被归因于 DataContract/DataMember 以避免引用 protobuf-net。谢谢。 @mark - 是的;yourMetaType[3].AsReference = true;
,其中3
是字段编号(DCS 用语中的Order=3
)
那么 Marc,这个图序列化在幕后是如何工作的?您是否为每个引用的对象创建隐藏的 int id(如代理主键),然后在加载时恢复它们?
@Lone 是的,就是这样 - 仅适用于标记为此用法的关系
太棒了。本周末,我将尝试将它用于 Ludem Dare 的快速而肮脏的序列化程序 (ludumdare.com/compo/rules)。需要很多很棒的忍者工具,比如你在这里制作的那个!以上是关于协议缓冲区是不是支持具有共享引用的对象图的序列化?的主要内容,如果未能解决你的问题,请参考以下文章