开发者

Does protocol buffers support serialization of object graphs with shared references?

开发者 https://www.devze.com 2023-03-07 06:44 出处:网络
Please, observe the following simple program (based on the example from the protobuf-net project v1 wiki):

Please, observe the following simple program (based on the example from the protobuf-net project 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 };
     开发者_StackOverflow中文版 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));
    }
  }
}

The second assertion fails. Is this a bug in the protobuf-net implementation or is it that protocol buffers simply does not support object graphs with shared references?

Thanks.


protocol-buffers itself does not support this - so no, it is not a bug. Indeed, XmlSerializer and DataContractSerializer* would do the same (and probably so would JavaScriptSerializer and JSON.NET).

However, it is a common request, so this is supported in protobuf-net v2 (basically: I cheat). Just change it to:

    [ProtoMember(3, AsReference=true)]
    public Address Address { get; set; }

(and use the v2 dll that I'm uploading in about 5 minutes, or build from code)


*=caveat: DataContractSerializer does support references, but only if you use a specific constructor; it is disabled by default

0

精彩评论

暂无评论...
验证码 换一张
取 消