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

Posted

技术标签:

【中文标题】Protobuf-net 创建具有接口和抽象基类的类型模型【英文标题】:Protobuf-net creating typemodel with interface and abstract baseclass 【发布时间】:2012-02-21 13:20:26 【问题描述】:

我正在尝试使用出色的 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】:

2 个问题:

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

认为以下内容符合您的描述...?

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

【讨论】:

与往常一样,anwser 显然非常简单,这就像一个魅力。非常感谢您的快速回复。

以上是关于Protobuf-net 创建具有接口和抽象基类的类型模型的主要内容,如果未能解决你的问题,请参考以下文章

Protobuf-net 包括不可序列化基类的特定成员

Java学习笔记二()

第七周课程总结&实验报告

在不破坏现有基类的情况下向具有许多派生类的抽象基类添加新方法

Protobuf-net RuntimeTypeModel 不序列化基类的成员

C ++从具有嵌套类的接口派生