可以添加新的ProtoInclude属性以不破坏向后兼容性

时间:2014-10-28 07:30:58

标签: c# serialization protobuf-net

我们遇到了向后兼容性问题,我们在其中添加了一个protobufed接口的新子类,但这意味着在以前的版本中无法打开此对象。

一般情况下这是可以的,所有我们的反序列化对象都是单独完成的,因此反序列化的失败不能解决其他问题。不幸的是,这个接口在列表中被序列化,因此在该类中存在新类型的对象将导致整个列表不被反序列化。

有没有办法在当前版本中标记班级或列表,以便版本只会省略那些无法满足的对象。

太明确了,我们想知道如何修改此问题的序列化方面的内容。

复制异常的测试:

using System.IO;
using NUnit.Framework;
using ProtoBuf;

namespace UnitTest.ProtoBuf
{

    [ProtoContract]
    [ProtoInclude(1, typeof(ImplementorInV2))]
    internal interface IInterfaceV2
    {
    }

    [ProtoContract]
    internal interface IInterfaceV1
    {
    }

    [ProtoContract]
    internal class ImplementorInV2 : IInterfaceV2
    {
        [ProtoMember(1)]
        public string Member { get; set; }
    }

    [TestFixture, Category("Framework")]
    internal class ProtoIncludeAddedTest
    {
        [Test]
        public void BasicTest()
        {
            var a = new ImplementorInV2();
            a.Member = "bla bla";
            byte[] buffer;
            IInterfaceV1 aCopy;
            using (var stream = new MemoryStream())
            {
                Serializer.Serialize(stream, a);
                buffer = stream.ToArray();
            }
            using (var stream = new MemoryStream(buffer))
            {
                aCopy = Serializer.Deserialize<IInterfaceV1>(stream);
            }
        }
    }
}

1 个答案:

答案 0 :(得分:1)

一般来说:是 - 是的;在您的特定情况下 - 可能不是,基本上。如果这是类继承,它将反序列化尽可能击败已知的继承链,即如果你有

[ProtoContract]
class Foo {} // v1

[ProtoContract, ProtoInclude(1, typeof(Bar))]
class Foo {}
[ProtoContract]
class Bar : Foo {} // v2

然后在v2中序列化Bar,v1客户端只需将其反序列化为Foo并忽略意外数据。但是,在您的情况下,问题是接口没有默认实现 - 它无法创建任何内容。 实际上是一种指定为列表等创建的默认类型的方法,正是出于这个原因,但是在您部署之前,您可能只需要部署v2代码。< / p>