protobuf-net deserialize base class to inherited c

2019-08-03 16:50发布

问题:

I have base class which is serialized.

[ProtoContract]
public class Web2PdfEntity 
{   


        [ProtoMember(1)]
        public string Title { get; set; }
        [ProtoMember(2)]
        public string CUrl { get; set; }
}

I would like to deserialize Web2PdfEntity class to Web2PdfServer which is inherited from Web2PdfEntity.

public class Web2PdfServer : Web2PdfEntity
{

public void MyServerMethod {}
public void MyServerMethod2{}
}

I have tried to use code below to deserialize class, unfortunately the properties are not set.

var web2Pdf = Serializer.Deserialize<Web2PdfServer>("c:\Web2PdfEntity-class-to-serialize-file.bin");
web2Pdf.Title //<- not deserialized
web2Pdf.CURL //<- not deserialized

回答1:

(heavily revised)

Based on the comments, the scenario presented is:

  • there are two types, which happen to be subclasses in C#
  • in serialization, we just want to flatly swap between them - no inheritance code (i.e. so you can save as Web2PdfEntity and load as Web2PdfServer, or v.v.)

This is a little different to the normal use case, where inherited types expect inheritance during serialization (which changes the data), and unrelated types are interchangeable as long as the contract fits.

There are a couple of ways of approaching this; one minor issue is that by default it doesn't look at inherited properties, to avoid duplication. You could re-advertise them, but that is a bit ungainly. Personally, I think I'd be tempted to just tell it what to do during app-startup:

var metaType = RuntimeTypeModel.Default.Add(typeof(Web2PdfServer), false);
metaType.Add(1, "Title").Add(2, "CUrl");

Now your existing Serializer code will treat Web2PdfServer correctly, including the two properties as indicated.