将带有标记为AsReference的成员的类反序列化时的ProtoException

时间:2013-06-27 04:11:28

标签: .net serialization deserialization protobuf-net

我得到 ProtoException

ProtoBuf.ProtoException : Internal error; a key mismatch occurred

使用以下代码:

[ProtoContract]
class Foo { }

class MemberRemovedTest
{
    [ProtoContract]
    class V1
    {
        [ProtoMember(1, AsReference = true)]
        public Foo A { get; set; }

        [ProtoMember(2, AsReference =  true)]
        public Foo B { get; set; }
    }

    [ProtoContract]
    class V2
    {
        [ProtoMember(2, AsReference = true)]
        public Foo B { get; set; }
    }

    public void BasicTest()
    {
        var v1 = new V1();
        v1.A = new Foo();
        v1.B = new Foo();

        byte[] buffer;
        V2 v2;
        using (var stream = new MemoryStream())
        {
            Serializer.Serialize(stream, A);
            buffer = stream.ToArray();
        }
        using (var stream = new MemoryStream(buffer))
        {
            v2 = Serializer.Deserialize<V2>(stream); //Exception here
        }
    }
}

如果出现以下情况,会抛出异常:

  • 第二个成员是被删除的成员。
  • ProtoMemberA的{​​{1}}属性不是B
  • AsReference = trueA都没有设置B个实例。

我理解protobuf支持成员删除,但这似乎表明存在必须保留它们的情况。

这是Protobuf中的错误还是关于删除成员的错误假设?

调用堆栈异常:

Foo

1 个答案:

答案 0 :(得分:0)

嗯......好的,有趣的。该死的。使这种情况起作用可能是非常有问题的;如果没有成员,我们没有足够的元数据来反序列化对象 - 甚至只是知道它是一个可能作为以后出现的as-reference对象的占位符的对象。存储每个跳过的字段以供稍后处理是不切实际的 - 事实上,在非平凡的情况下,由于技术原因(如果as-reference是子对象,可能是几个)降低,作为成员更高的对象被删除 - 由于缺少元数据,我们无法处理它。)

我现在没有比“是,那不行”更好的评论。烦恼 - 有趣的场景。