首先让我们展示一个简单的测试案例以及如何触发它。这里是这个类:Protobuf.NET - 触发引用列表中的“检测到可能的递归”问题
class ProtoRecurseTest
{
private int nextPayload = 1;
public int Payload { get; private set; } = 0;
public ProtoRecurseTest Back { get; private set; } = null;
public List<ProtoRecurseTest> Children { get; set; } = new List<ProtoRecurseTest>();
public ProtoRecurseTest Add()
{
ProtoRecurseTest result = new ProtoRecurseTest(this, nextPayload++);
Children.Add(result);
return result;
}
public ProtoRecurseTest()
{
}
private ProtoRecurseTest(ProtoRecurseTest parent, int payload)
{
Back = parent;
this.Payload = payload;
nextPayload = payload + 1;
}
private static void ToStringHelper(ProtoRecurseTest proto, StringBuilder sb)
{
sb.Append(proto.Payload + " -> ");
// another little hassle of protobuf due to empty list -> null deserialization
if (proto.Children != null)
{
foreach (var child in proto.Children)
ToStringHelper(child, sb);
}
}
public override string ToString()
{
StringBuilder sb = new StringBuilder();
ToStringHelper(this, sb);
return sb.ToString();
}
}
没有protobuf注释,因为这是由编程的照顾。我已经手动确保将类和Back以及Children都添加到模式中.AsReferenceDefault = true。
递归触发发生在一个实例填充到至少8个足够奇怪的深度时。 7很好。人口代码很简单:
ProtoRecurseTest recurseTest = new ProtoRecurseTest();
ProtoRecurseTest recurseItem = recurseTest;
for (int i = 0; i < 8; i++)
recurseItem = recurseItem.Add();
然后序列化recurseTest。这种行为只发生在儿童在列表中,但在列表中出现时,即使每个列表中只有1个孩子,也会出现这种情况,因为您最终将从样本填充代码中得出结论。当我用一个参考替换孩子时,所有的事情都很顺利。
这是使用ProtoBuf.NET 2.1.0.0。