当对象的空构造函数为它的一个属性创建实例并将其自身作为参数传递时,似乎出现了一个问题。特别是当该实例是派生类型并且属性将被反序列化为不同的派生类型时。
我在我的应用程序中遇到了这个问题,并提取了一个单元测试来演示它:
public class ProtobufStackOverflowTest
{
[ProtoContract]
private class Node
{
public Node()
{
Composition = new VComposition(this);
}
[ProtoMember(1)]
public Composition Composition { get; set; }
}
[ProtoContract]
[ProtoInclude(10, typeof(GComposition))]
[ProtoInclude(11, typeof(VComposition))]
private abstract class Composition
{
}
[ProtoContract]
private class GComposition : Composition
{
}
[ProtoContract]
private class VComposition : Composition
{
public VComposition()
{
}
public VComposition(Node node)
{
}
}
[ProtoContract]
private class Model
{
[ProtoMember(1)]
public Node Source { get; set; }
}
[Test]
public void Testthing()
{
var model = new Model();
var sourceNode = new Node();
var sourceComposition = new VComposition();
sourceNode.Composition = sourceComposition;
model.Source = sourceNode;
Assert.DoesNotThrow(() => GetSerializedCopy(model));
}
public static byte[] Serialize<T>(T obj)
{
using (var stream = new MemoryStream())
{
Serializer.Serialize(stream, obj);
return stream.ToArray();
}
}
public static T Deserialize<T>(byte[] buffer)
{
using (var stream = new MemoryStream(buffer))
{
return Serializer.Deserialize<T>(stream);
}
}
public static T GetSerializedCopy<T>(T obj) { return Deserialize<T>(Serialize(obj)); }
}
运行后,结果为:
类型为"System"的未处理异常。在protobuf-net.dll中发生StackOverflowException
我看到的调用堆栈完全由以下代码块重复组成:
protobuf-net.dll!ProtoBuf.Serializers.CompiledSerializer.ProtoBuf.Serializers.IProtoSerializer.Read(object value, ProtoBuf.ProtoReader source) + 0x51 bytes
protobuf-net.dll!ProtoBuf.Meta.RuntimeTypeModel.Deserialize(int key, object value, ProtoBuf.ProtoReader source) + 0x1fe bytes
protobuf-net.dll!ProtoBuf.Meta.TypeModel.DeserializeCore(ProtoBuf.ProtoReader reader, System.Type type, object value, bool noAutoCreate) + 0xa5 bytes
protobuf-net.dll!ProtoBuf.Meta.TypeModel.Deserialize(System.IO.Stream source, object value, System.Type type, ProtoBuf.SerializationContext context) + 0xd7 bytes
protobuf-net.dll!ProtoBuf.Meta.TypeModel.Deserialize(System.IO.Stream source, object value, System.Type type) + 0x4f bytes
protobuf-net.dll!ProtoBuf.ProtoReader.Merge(ProtoBuf.ProtoReader parent, object from, object to) + 0x19a bytes
[Lightweight Function]
protobuf-net.dll!ProtoBuf.Serializers.CompiledSerializer.ProtoBuf.Serializers.IProtoSerializer.Read(object value, ProtoBuf.ProtoReader source) + 0x51 bytes
protobuf-net.dll!ProtoBuf.Meta.RuntimeTypeModel.Deserialize(int key, object value, ProtoBuf.ProtoReader source) + 0x1fe bytes
protobuf-net.dll!ProtoBuf.Meta.TypeModel.DeserializeCore(ProtoBuf.ProtoReader reader, System.Type type, object value, bool noAutoCreate) + 0xa5 bytes
protobuf-net.dll!ProtoBuf.Meta.TypeModel.Deserialize(System.IO.Stream source, object value, System.Type type, ProtoBuf.SerializationContext context) + 0xd7 bytes
protobuf-net.dll!ProtoBuf.Meta.TypeModel.Deserialize(System.IO.Stream source, object value, System.Type type) + 0x4f bytes
protobuf-net.dll!ProtoBuf.ProtoReader.Merge(ProtoBuf.ProtoReader parent, object from, object to) + 0x19a bytes
[Lightweight Function]
使用版本2.0.0.640的protobuf-net
任何关于导致这种情况发生的信息将非常感激
我也有同样的问题,v2.1.0-alpha-1版本修复了这个问题。
https://github.com/mgravell/protobuf-net/releases问候,
Pluc