3
votes

I'm using protobuf-net version 2.0.0.640 to serialize some data as shown below.

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

Now, If I declare an inheritance dependency between 'ITestMessage' & 'MyOrder' via code using:

RuntimeTypeModel.Default[typeof(ITestMessage)].AddSubType(2, typeof(MyOrder));

I get the following error when trying to deserialize my prevously saved data. "No parameterless constructor found for 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);
    }
}

Can someone please explain why this would happen when 'MyOrderWrapper' does not reference anything higher than 'MyOrder' in the inheritance hirarchy.

Also, why it works when I explictly include '[ProtoInclude(2, typeof(MyOrder))]' on 'ITestMessage'

Thanks

1

1 Answers

1
votes

Basically, that is a breaking change as far as the serializer is concerned - at the wire layer, neither "classes" nor "interfaces" exist, so in terms of storage, this is akin to changing the base-type of the class; when serializing, the root type was MyOrder - and during deserialization the root type is ITestMessage. This will not make it happy.

Basically: you can't do that.