在玩新发布的protobuf.net时,我们遇到了以下代码中说明的问题:
[ProtoContract]
class Node
{
public Node()
{
ChildLinks = new List<Link>();
ParentLinks = new List<Link>();
}
[ProtoMember(1, IsRequired = true)]
public string Data { get; set; }
[ProtoMember(2, IsRequired = true)]
public List<Link> ChildLinks { get; set; }
[ProtoMember(3, IsRequired = true)]
public List<Link> ParentLinks { get; set; }
public void AddChild(Node child)
{
Link link = new Link { Parent = this, Child = child };
ChildLinks.Add(link);
child.ParentLinks.Add(link);
}
}
[ProtoContract]
class Link
{
[ProtoMember(2, AsReference = true, IsRequired = true)]
public Node Child { get; set; }
[ProtoMember(3, AsReference = true, IsRequired = true)]
public Node Parent { get; set; }
}
public static void Main()
{
Node node = new Node { Data = "parent" };
node.AddChild(new Node { Data = "child" });
using (MemoryStream memStream = new MemoryStream())
{
Serializer.Serialize(memStream, node);
memStream.Position = 0;
Node deserialized = Serializer.Deserialize<Node>(memStream);
Link childLink = deserialized.ChildLinks.Single();
Debug.Assert(ReferenceEquals(childLink, childLink.Child.ParentLinks.Single()));
}
}
断言抛出异常......我们的目标是在ChildLinks和ParentLinks属性中拥有一个Link对象的唯一实例。我们尝试了AsReference属性,但它没有用......
有谁知道我们如何解决这个问题?
答案 0 :(得分:1)
我仍然需要评估影响(当我的头感觉像奶酪时,不要做干的事情),但是图中的 root 对象有一个麻烦点 - 意思是:因为我通常在执行关联时处理引用跟踪,而在根对象上 没有关联。我想我可以用一些类型级属性来解决这个问题(即总是将视为参考)。
无论如何,现在你可以通过向图表添加一个级别(人工添加关联)来支持这一步骤,即
static class Program
{
public static void Main()
{
Node node = new Node { Data = "parent" };
node.AddChild(new Node { Data = "child" });
using (MemoryStream memStream = new MemoryStream())
{
Serializer.Serialize(memStream, new NodeWrapper { Root = node });
memStream.Position = 0;
Node deserialized = Serializer.Deserialize<NodeWrapper>(memStream).Root;
Link childLink = deserialized.ChildLinks.Single();
Debug.Assert(ReferenceEquals(childLink, childLink.Child.ParentLinks.Single()));
}
}
}
[ProtoContract]
class NodeWrapper
{
[ProtoMember(1, AsReference = true, IsRequired = true)]
public Node Root {get;set;}
}