Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Protobuf net创建带有接口和抽象基类的typemodel_C#_.net_Protocol Buffers_Protobuf Net - Fatal编程技术网

C# Protobuf net创建带有接口和抽象基类的typemodel

C# Protobuf net创建带有接口和抽象基类的typemodel,c#,.net,protocol-buffers,protobuf-net,C#,.net,Protocol Buffers,Protobuf Net,我正在尝试使用伟大的Protobuf网络序列化一个模型。我不能使用属性(对象在编译时是未知的),所以我构建了一个类型模型。 我的对象模型由一个类TestDataObject组成,这个类有一个ITestDataExtension属性。抽象基类TestDataExtensionBase实现此接口 类TestDataExtension(代码中的myDataObjectExtA)继承自该基类 我的TypeModel是这样构造的: System.IO.MemoryStream tmpMem

我正在尝试使用伟大的Protobuf网络序列化一个模型。我不能使用属性(对象在编译时是未知的),所以我构建了一个类型模型。 我的对象模型由一个类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();
        MetaType extBaseType = interfaceType.AddSubType(100, typeof(TestDataExtensionBase));
        MetaType extType = extBaseType.AddSubType(200, myDataObjectExtA.GetType());
如果我运行以下命令,基类的属性不会序列化,我需要序列化它们。
在我看来,我应该为TestDataExtensionBase添加一个子类型,如下所示:

        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();
        MetaType extBaseType = interfaceType.AddSubType(100, typeof(TestDataExtensionBase));
        MetaType extType = extBaseType.AddSubType(200, myDataObjectExtA.GetType());
但这会导致:意外的子类型:TestDataExtension。 有人知道我做错了什么吗?任何帮助都将不胜感激。

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);
    }
}
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显然非常简单,它就像一个符咒。非常感谢您的快速响应。因为anwser通常看起来非常简单,它就像一个符咒。非常感谢您的快速回复。