我正在尝试序列化具有不可变基类的不可变消息。但是,我无法说服protobuf-serializer将其反序列化为派生类型。简而言之,此测试为我提供了无效的强制转换异常(从Base到Derived):

[TestFixture]
public class InheritanceTest
{
    public class Base
    {
        public int IntField { get; private set; }

        public Base(int intField)
        {
            IntField = intField;
        }
    }

    public class Derived : Base
    {
        public string StringField { get; private set; }

        public Derived(int intField, string stringField) : base(intField)
        {
            StringField = stringField;
        }
    }

    [Test]
    public void TestInheritance()
    {
        var serializer = TypeModel.Create();
        serializer.Add(typeof (Base), true)
            .Add(1, "IntField")
            .AddSubType(2, typeof (Derived))
            .UseConstructor = false;

        serializer.Add(typeof (Derived), true)
            .Add(1, "StringField")
            .UseConstructor = false;

        serializer.CompileInPlace();

        using (var stream = new MemoryStream())
        {
            var message = new Derived(1, "Some text that is not important");

            serializer.Serialize(stream, message);
            stream.Position = 0;

            var retrieved = (Derived) serializer.Deserialize(stream, null, typeof (Derived));

            Assert.AreEqual(message.IntField, retrieved.IntField);
            Assert.AreEqual(message.StringField, retrieved.StringField);
        }
    }

}


如果将Base和Derived转换为可变类型,则此异常消失。我做错什么了吗?还是protobuf-net的局限性?

最佳答案

这似乎是元组检测的副作用,导致它具有特定的代码分支。优点是,只需将true更改为false,就应该能够从原始代码中修复该问题。此参数告诉您是否要应用标准行为。您不需要它,因为您可以自己定义模型。

        var serializer = TypeModel.Create();
        serializer.Add(typeof (Base), false)
            .Add(1, "IntField")
            .AddSubType(2, typeof (Derived))
            .UseConstructor = false;

        serializer.Add(typeof (Derived), false)
            .Add(1, "StringField")
            .UseConstructor = false;


请注意,我尚未对此进行验证-我稍后会进行检查。

10-04 23:10
查看更多