问题描述
|
给出以下代码:
[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);
}
}