ProtoBuf,继承和泛型

问题描述

| 给出以下代码
[Serializable,ProtoContract]
[ProtoInclude(100,typeof(ValueA))]
[ProtoInclude(101,typeof(ValueB))]
public class Value
{
}

[Serializable,ProtoContract]
public class ValueA : Value
{
}

[Serializable,ProtoContract]
public class ValueB : Value
{
}

[Serializable,ProtoContract]
[ProtoInclude(1000,typeof(ContainerA))]
[ProtoInclude(1001,typeof(ContainerB))]
public class Container<T> where T : Value
{
    [ProtoMember(1)]
    public T Item;
}

[Serializable,ProtoContract]
public class ContainerA : Container<ValueA>
{
}

[Serializable,ProtoContract]
public class ContainerB : Container<ValueB>
{
}
尝试序列化ContainerA / ContainerB时出现错误:   ProtoBuf.ProtoException:已知类型   用于ProtoIncludeAttribute的ContainerB   必须是的直接子类   容器1 注释掉以下行之一-以便仅一个类从Container继承-将使ProtoBuf再次感到高兴:
[ProtoInclude(1000,typeof(ContainerB))]
这是怎么回事,该怎么办? TIA     

解决方法

我仍在等待更多信息,但是最终从开放泛型类型继承还是有些棘手。也许,如果我了解确切的模型,则可以添加更多内容,但是可以进行以下工作:
using System.Diagnostics;
using ProtoBuf;
[ProtoContract]
[ProtoInclude(1,typeof(ValueA))]
[ProtoInclude(2,typeof(ValueB))]
public class Value
{
}

[ProtoContract]
public class ValueA : Value
{
}

[ProtoContract]
public class ValueB : Value
{
}
[ProtoContract]
[ProtoInclude(1,typeof(Container<ValueA>))]
[ProtoInclude(2,typeof(Container<ValueB>))]
public abstract class Container
{

    public abstract Value BaseValue { get; set; }
}
[ProtoContract]
public class Container<T> : Container where T : Value
{
    [ProtoMember(1)]
    public T Value { get; set;}

    public override Value BaseValue
    {
        get { return Value; }
        set { Value = (T)value; }
    }
}

static class Program
{
    static void Main()
    {
        var model = new Container<ValueA>();
        model.Value = new ValueA();
        var clone = Serializer.DeepClone(model);
        Debug.Assert(clone.Value is ValueA);
    }
}
尽管实际上
ValueA
ValueB
之间的关系完全没有必要,除非您需要:
using System.Diagnostics;
using ProtoBuf;

[ProtoContract]
public class ValueA
{
}

[ProtoContract]
public class ValueB
{
}

[ProtoContract]
[ProtoInclude(1,typeof(Container<ValueB>))]
public abstract class Container
{

    public abstract object BaseValue { get; set; }
}
[ProtoContract]
public class Container<T> : Container
{
    [ProtoMember(1)]
    public T Value { get; set;}

    public override object BaseValue
    {
        get { return Value; }
        set { Value = (T)value; }
    }
}

static class Program
{
    static void Main()
    {
        var model = new Container<ValueA>();
        model.Value = new ValueA();
        var clone = Serializer.DeepClone(model);
        Debug.Assert(clone.Value is ValueA);
    }
}