【问题标题】:Protobuf-net recursion exception is not thrown anymore, when removing the parent class from my object graph从我的对象图中删除父类时,不再抛出 Protobuf-net 递归异常
【发布时间】:2015-08-21 09:00:36
【问题描述】:

我在尝试序列化我的对象图时收到以下错误消息:

Possible recursion detected (offset: 4 level(s)): TestProtobufSerialization.Program+SI

我的模型如下所示:

    [ProtoContract(ImplicitFields = ImplicitFields.AllPublic, AsReferenceDefault = true)]
    [ProtoInclude(101, typeof(ST))]
    [ProtoInclude(102, typeof(SI))]
    public class Base 
    {
        public string CreateBy { get; set; }
        public string ModifiedBy { get; set; }
    }

    [ProtoContract(ImplicitFields = ImplicitFields.AllPublic, AsReferenceDefault = true)]
    public class ST : Base
    {
        public string Id { get; set; }
        public List<SI> Indexes { get; set; }
    }

    [ProtoContract(ImplicitFields = ImplicitFields.AllPublic, AsReferenceDefault = true)]
    public class SI : Base
    {
        public string Id { get; set; }
        public ST ST { get; set; }
    }

实际要序列化的代码如下:

        var st = new ST() { Id = "ST001" };
        var si = new SI() { Id = "SI001" };

        st.Indexes = new List<SI>();
        st.Indexes.Add(si);
        si.ST = st;


        ST newST = serializeDeserializeWithProto<ST>(st, "testing_cyclic_references");

        Debug.Assert(st != null, "ST is null!");

辅助方法是:

    private static T serializeDeserializeWithProto<T>(T input, string fileName)
    {
        using (var file = File.Create(fileName + ".bin"))
        {
            Serializer.Serialize(file, input);
        }

        T output;
        using (var file = File.OpenRead(fileName + ".bin"))
        {
            output = Serializer.Deserialize<T>(file);
        }

        string proto = Serializer.GetProto<T>();
        File.WriteAllText(typeof(T).ToString() + "_proto.txt", proto, Encoding.ASCII);

        Console.WriteLine(proto);

        return output;
    }

当我尝试运行此代码时,我得到了上述异常。有趣的是,如果我从 ST 和 SI 类中删除 Base 类,则序列化工作。我想了解为什么序列化在没有 Base 类的情况下工作,并且它不适用于作为 ST 和 SI 父级的 Base 类。

我还创建了一个gist for my repro 代码。

【问题讨论】:

  • 但是你有一个循环,对吧?
  • @JamesBarrass 我认为这与您链接到的问题重复。我正在寻找关于为什么从我的模型类中删除 Base 类可以解决循环引用问题的答案。我花了几个小时在我的代码中追踪问题,然后充分简化问题,所以我可以在这里展示它。我可能需要改写标题和我的问题,所以它看起来不像是重复的。
  • @helb 是的,我总是有一个循环,但是当基类不是 ST 和 SI 的父类时,我没有得到异常。

标签: c# protobuf-net


【解决方案1】:

我想我找到了答案。在更改 ST 类型中重复属性的声明方式时,我没有更多例外:

[ProtoContract(ImplicitFields = ImplicitFields.AllPublic, AsReferenceDefault = true)]
public class ST : Base
{
    public string Id { get; set; }

    [ProtoMember(401, AsReference = true)]
    public List<SI> Indexes { get; set; }
}

当我声明我希望所有公共属性都被序列化为引用时,我仍然不明白为什么我需要为集合属性添加一个额外的属性。我发布了一个后续问题以找出答案:

Difference between how ProtoContract AsReference works when applied on a repeated property compared to a normal property

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-19
    • 1970-01-01
    • 2021-10-20
    • 1970-01-01
    • 2015-12-14
    相关资源
    最近更新 更多