Protobuf-сеть, создающая typemodel с интерфейсом и абстрактным базовым классом - PullRequest
2 голосов
/ 21 февраля 2012

Я пытаюсь сериализовать модель, используя отличный Protobuf-NET.Я не могу использовать атрибуты (объекты неизвестны во время компиляции), поэтому я создал TypeModel.Моя объектная модель состоит из класса TestDataObject , этот класс имеет свойство ITestDataExtension .Абстрактный базовый класс TestDataExtensionBase реализует этот интерфейс, и класс TestDataExtension (myDataObjectExtA в коде) наследуется от этого базового класса.

Мой 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.Кто-нибудь знает, что я делаю не так?Любая помощь будет оценена.

1 Ответ

4 голосов
/ 21 февраля 2012

2 проблемы:

  • Поддержка интерфейса в настоящее время предоставляется только для членов , а не корневых объектов (из-за проблем множественного наследования интерфейса);самый простой способ обойти это - использовать объект-оболочку с элементом интерфейса
  • , для которого необходимо определить подтипы в модели

I думать следующее делает то, что вы описываете ...?

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