Protobuf-net定义继承后的反序列化

3
我正在使用protobuf-net 2.0.0.640版本来序列化一些数据,如下所示。
[ProtoContract(ImplicitFields = ImplicitFields.AllFields)]
public interface ITestMessage
{

}

[ProtoContract(ImplicitFields = ImplicitFields.AllFields)]
public class MyOrder : ITestMessage
{
    public int Amount { get; set; }
}

[ProtoContract(ImplicitFields = ImplicitFields.AllFields)]
public class MyOrderWrapper
{
    public MyOrder Order { get; set; }
}

[TestMethod]
public void TestOrderSerialize()
{
    var order = new MyOrder() {Amount = 10};
    var orderWrapper = new MyOrderWrapper() { Order = order };

    using (var file = File.Create("C:\\temp\\order.bin"))
    {
        Serializer.Serialize<MyOrderWrapper>(file, orderWrapper);
    }
}

现在,如果我通过代码在“ITestMessage”和“MyOrder”之间声明了继承依赖关系:
RuntimeTypeModel.Default[typeof(ITestMessage)].AddSubType(2, typeof(MyOrder));

尝试反序列化之前保存的数据时,我遇到了以下错误: “找不到ITestMessage的无参构造函数”。
[TestMethod]
public void TestOrderDeserialize()
{
    RuntimeTypeModel.Default[typeof(ITestMessage)].AddSubType(2, typeof(MyOrder));

    MyOrderWrapper orderWrapper;
    using (var file = File.OpenRead("C:\\temp\\order.bin"))
    {
        orderWrapper = Serializer.Deserialize<MyOrderWrapper>(file);
    }
}

请问为什么在继承层次结构中'MyOrderWrapper'没有引用比'MyOrder'更高的任何内容时会出现这种情况?

此外,为什么当我在'ITestMessage'上明确包含'[ProtoInclude(2, typeof(MyOrder))]时它能够正常工作?

谢谢

1个回答

1
基本上,这对于序列化程序来说是一个重大的变化——在传输层面上,既不存在“类”也不存在“接口”,因此在存储方面,这相当于更改类的基础类型;在序列化时,根类型是MyOrder,而在反序列化时,根类型是ITestMessage。这会导致问题。
基本上:你不能这样做。

为什么明确定义属性后它会起作用?还有,您有什么建议可以解决这个问题吗?例如,读取先前的数据,然后构建一个新模型来包含关系。 - Prin
@Prin 你的意思是“另外,为什么当我在 'ITestMessage' 上显式包含 '[ProtoInclude(2, typeof(MyOrder))] 时它就能工作” - 嗯;我得看一下,但我猜测它实际上从未成为模型的一部分;它会自动检测基类型上的合同,但我认为它不会遍历接口,因为这些接口在重要方面的工作方式非常不同。 - Marc Gravell

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接