使用 protobuf.net 序列化图形时出现问题

Posted

技术标签:

【中文标题】使用 protobuf.net 序列化图形时出现问题【英文标题】:issue while serializing graphs with protobuf.net 【发布时间】:2011-05-23 17:23:56 【问题描述】:

在使用新发布的 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 属性,但它不起作用...

有谁知道我们如何解决这个问题?

【问题讨论】:

嗨;我现在被一些可怕的虫子困住了。几乎无法阅读/思考。我会尽快查看此内容。 (要清楚——这里的“bug”是指“疾病”,而不是“软件问题”) 清除液体并休息,先生。最后,我可以帮助 Marc 解决一个问题:) 【参考方案1】:

我仍然需要评估影响(当我的头感觉像奶酪时,不是要干的事情),但是有一个.... 图表中 root 对象的问题点 -含义:因为我通常在走关联时处理引用跟踪,而在根对象上没有关联。我想我可能可以用一些类型级别的属性来解决这个问题(即 always 视为参考)。

无论如何,现在您可以通过向图表添加更多级别(人为添加关联)来避开这一点,即

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;

【讨论】:

感谢您的回答。在阅读并使用新的 dll 进行更多操作后,关于“AsReference”这个属性的事情变得更加清晰了 @PierrOz 酷;为此,我将继续研究修复根对象

以上是关于使用 protobuf.net 序列化图形时出现问题的主要内容,如果未能解决你的问题,请参考以下文章

使用 Protobuf .net 反序列化单个结构字段

Protobuf-net - 啥被序列化了?

Protobuf.net 内存使用情况

protobuf.net 和条件序列化

Protobuf.net 异常 - 检查元数据时超时

列表的 Protobuf.net 对象图序列化