用protobuf反序列化简单继承模型出错

本文关键字:模型 出错 继承 简单 protobuf 反序列化 | 更新日期: 2023-09-27 18:11:40

当对象的空构造函数为它的一个属性创建实例并将其自身作为参数传递时,似乎出现了一个问题。特别是当该实例是派生类型并且属性将被反序列化为不同的派生类型时。

我在我的应用程序中遇到了这个问题,并提取了一个单元测试来演示它:

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

任何关于导致这种情况发生的信息将非常感激

用protobuf反序列化简单继承模型出错

我也有同样的问题,v2.1.0-alpha-1版本修复了这个问题。

https://github.com/mgravell/protobuf-net/releases

问候,

Pluc