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

时间:2015-09-07 06:14:23

标签: c# protobuf-net

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

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

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)); }
}

运行时,会得到以下结果:

  

protobuf-net.dll中发生未处理的“System.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]  

使用protobuf-net的2.0.0.640版本

非常感谢任何导致此事件发生的信息

1 个答案:

答案 0 :(得分:0)

我有同样的问题,发布版本v2.1.0-alpha-1解决了这个问题。

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

此致

PLUC