Protobuf-net crea typemodel con interfaccia e baseclass astratte

Sto provando a serializzare un modello usando l’ottimo Protobuf-NET. Non posso usare gli attributi (gli oggetti sono sconosciuti in fase di compilazione), quindi ho costruito un TypeModel. Il mio modello a oggetti è costituito da una class TestDataObject , questa class ha una proprietà di ITestDataExtension . La baseclass astratta TestDataExtensionBase implementa questa interfaccia e la class TestDataExtension (myDataObjectExtA nel codice) eredita da questa class di base.

My TypeModel è costruito in questo modo:

System.IO.MemoryStream tmpMemoryStream = new System.IO.MemoryStream(); RuntimeTypeModel model = TypeModel.Create(); MetaType basetype = model.Add(typeof(TestDataObject), true); MetaType interfaceType = model.Add(typeof(ITestDataExtension), true); //MetaType extBaseType = interfaceType.AddSubType(100, typeof(TestDataExtensionBase)); MetaType extType = interfaceType.AddSubType(200, myDataObjectExtA.GetType()); model.Add(typeof(TestDataExtensionBase), true); model.Add(myDataObjectA.Ext.GetType(), true); model.CompileInPlace(); model.Serialize(tmpMemoryStream, myDataObjectA); byte[] tmpDat = tmpMemoryStream.ToArray(); 

Se eseguo quanto segue, le proprietà della class base non sono serializzate e ho bisogno che vengano serializzate.
A mio parere avrei dovuto aggiungere un sottotipo per TestDataExtensionBase in questo modo:

  MetaType extBaseType = interfaceType.AddSubType(100, typeof(TestDataExtensionBase)); MetaType extType = extBaseType.AddSubType(200, myDataObjectExtA.GetType()); 

Ma questo si traduce in un sottotipo inatteso: TestDataExtension. Qualcuno sa che cosa sto sbagliando? Qualsiasi aiuto sarebbe apprezzato.

2 numeri:

  • il supporto di interfaccia è attualmente fornito solo per i membri , non per gli oggetti radice (a causa dei problemi di ereditarietà dell’interfaccia multipla); il modo più semplice è utilizzare un object wrapper con un membro dell’interfaccia
  • è necessario definire i sottotipi nel modello

Penso che quanto segue fa ciò che descrivi …?

 using System; using ProtoBuf.Meta; interface ITest { int X { get; set; } } abstract class TestBase : ITest { public int X { get; set; } // from interface public int Y { get; set; } } class Test : TestBase { public int Z { get; set; } public override string ToString() { return string.Format("{0}, {1}, {2}", X, Y, Z); } } class Wrapper { public ITest Value { get; set; } } public class Program { static void Main() { var model = TypeModel.Create(); model.Add(typeof (ITest), false).Add("X") .AddSubType(10, typeof (TestBase)); model.Add(typeof (TestBase), false).Add("Y") .AddSubType(10, typeof (Test)); model.Add(typeof (Test), false).Add("Z"); model.Add(typeof (Wrapper), false).Add("Value"); Wrapper obj = new Wrapper {Value = new Test() {X = 123, Y = 456, Z = 789}}; var clone = (Wrapper)model.DeepClone(obj); Console.WriteLine(clone.Value); } }