Protobuf-net创建具有接口和抽象基类的类型模型

我正在尝试使用伟大的Protobuf-NET序列化模型。 我不能使用属性(对象在编译时是未知的),所以我构造了一个TypeModel。 我的对象模型由一个类TestDataObject组成 ,该类具有ITestDataExtension属性。 抽象基类TestDataExtensionBase实现此接口,类TestDataExtension (代码中的myDataObjectExtA)inheritance自此基类。

我的TypeModel构造如下:

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(); 

如果我运行以下命令,基类的属性不会被序列化,我需要序列化它们。
在我看来,我应该为TestDataExtensionBase添加一个子类型,如下所示:

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

但这会导致:意外的子类型:TestDataExtension。 有谁知道我做错了什么? 任何帮助,将不胜感激。

2个问题:

  • 接口支持目前仅为成员提供,而不是根对象(由于多接口inheritance的问题); 最简单的方法是使用带有接口成员的包装器对象
  • 有必要在模型中定义子类型

认为以下是你所描述的……?

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