我正在尝试使用protobuf-net库序列化一组对象。我遇到的问题是集合中的顶级对象没有被设置为图形中的引用,因此当它们在序列化子节点中被进一步向下引用时,它们将被重新序列化并在此时作为引用创建。有没有办法让顶级对象被序列化为引用?我已经阅读了几个相互矛盾的帖子,似乎表明protobuf-net现在支持这一点,而其他帖子似乎建议在顶级对象周围创建一个包装器以启用此行为。感谢...
以下是显示我的问题的示例程序。如您所见,引用不相等。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ProtoBuf;
namespace ProtoBufTest
{
[ProtoContract(AsReferenceDefault=true)]
public class Foo
{
[ProtoMember(1, AsReference=true)]
public FooChild Child;
[ProtoMember(2)]
public Guid Id;
}
[ProtoContract]
public class FooChild
{
[ProtoMember(1, AsReference=true)]
public Foo Parent;
}
class Program
{
static void Main(string[] args)
{
List<Foo> foos = new List<Foo>()
{
new Foo() { Child = new FooChild(), Id = Guid.NewGuid() }
};
foos[0].Child.Parent = foos[0];
var clone = Serializer.DeepClone(foos);
Console.WriteLine(ReferenceEquals(clone[0], clone[0].Child.Parent));
Console.WriteLine(clone[0].Id == clone[0].Child.Parent.Id);
}
}
}
答案 0 :(得分:0)
如果你的确意味着根对象(即传递给Serialize
的对象),那么这应该只是起作用,例如:
using ProtoBuf;
using System;
[ProtoContract]
public class Foo
{
[ProtoMember(1)]
public Bar Bar { get; set; }
}
[ProtoContract]
public class Bar
{
[ProtoMember(1, AsReference = true)]
public Foo Foo { get; set; }
}
static class Program
{
static void Main()
{
var foo = new Foo { Bar = new Bar() };
foo.Bar.Foo = foo;
var clone = Serializer.DeepClone(foo);
// writes: True
Console.WriteLine(ReferenceEquals(clone, clone.Bar.Foo));
}
}
如果不正在工作,那么我怀疑它实际上并不是 root ,而只是图中的高位(但非根) - 在这种情况下,添加AsReference=true
应该修复它。
请注意,我也过期了一个公开发布,但源代码现在可以更好地支持在合同级别表达这一点 - 这将包含在下一个版本中。例如(在这里从内存工作):
[ProtoContract(AsReferenceDefault=true)]
public class Foo
{
[ProtoMember(1)]
public Bar Bar { get; set; }
}
这隐含地假设任何Foo
成员都应序列化为 ,除非 明确禁用它们(AsReference=false
)。