如何用泛型基类定义protobuf-net模型



给定这些类型:

  [DataContract]
  public class EntityId
  {
    [DataMember(Order = 1)]
    public string IdAsString { get; set; }
    [DataMember(Order = 2), XmlIgnore]
    public Type Type { get; set; }
    #region XML hacks
    [XmlElement("Type"), Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
    public string AssemblyQualifiedTypeName
    {
      get { return ValueConverter.Default.Type2String(Type); }
      set { Type = ValueConverter.Default.String2Type(value); }
    }
    #endregion
  }
  [DataContract]
  public class EntityRelation
  {
    [DataMember(Order = 1)]
    public int Id { get; set; }
    [DataMember(Order = 2)]
    public string Path { get; set; }
  }
  [DataContract]
  public class Base<TId>
  {
    [DataMember(Order = 1)]
    public TId Id { get; set; }
    [DataMember(Order = 2)]
    public string Name { get; set; }
    [DataMember(Order = 3)]
    public EntityId ParentId { get; set; }
    [DataMember(Order = 4)]
    public int LastChanged { get; set; }
    [DataMember(Order = 5)]
    public string Description { get; set; }
    [DataMember(Order = 6)]
    public EntityRelation EntityRelation { get; set; }
  }
  [DataContract]
  public class FlowFolder : Base<int>
  {
  }

这个模型定义:

  var m = RuntimeTypeModel.Default;
  m.AutoCompile = false;
  m.Add(typeof(Base<int>), true).AddSubType(1, typeof(FlowFolder));

这个用法:

var entity = GetFlowFolder();
var typeTag = GetTypeTag(entity);
Model.SerializeWithLengthPrefix(stream, entity, null, PrefixStyle.Base128, typeTag);

我得到了这个异常:

System.InvalidOperationException occurred
  Message=Duplicate field-number detected; 1 on: NC.DTO.Base`1[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]
  Source=protobuf-net
  StackTrace:
       at ProtoBuf.Serializers.TypeSerializer..ctor(Type forType, Int32[] fieldNumbers, IProtoSerializer[] serializers, MethodInfo[] baseCtorCallbacks, Boolean isRootType, Boolean useConstructor, CallbackSet callbacks, Type constructType) in z:Workprotobuf-net-v2protobuf-netSerializersTypeSerializer.cs:line 43
  InnerException: 

具有以下堆栈跟踪:

protobuf-net.dll!ProtoBuf.Serializers.TypeSerializer.TypeSerializer(System.Type forType, int[] fieldNumbers, ProtoBuf.Serializers.IProtoSerializer[] serializers, System.Reflection.MethodInfo[] baseCtorCallbacks, bool isRootType, bool useConstructor, ProtoBuf.Meta.CallbackSet callbacks, System.Type constructType) Line 43   C#
protobuf-net.dll!ProtoBuf.Meta.MetaType.BuildSerializer() Line 283 + 0xe3 bytes C#
protobuf-net.dll!ProtoBuf.Meta.MetaType.Serializer.get() Line 209 + 0x11 bytes  C#
protobuf-net.dll!ProtoBuf.Meta.RuntimeTypeModel.Serialize(int key, object value, ProtoBuf.ProtoWriter dest) Line 357 + 0x51 bytes   C#
protobuf-net.dll!ProtoBuf.ProtoWriter.WriteObject(object value, int key, ProtoBuf.ProtoWriter writer, ProtoBuf.PrefixStyle style, int fieldNumber) Line 101 + 0x45 bytes    C#
protobuf-net.dll!ProtoBuf.Meta.TypeModel.SerializeWithLengthPrefix(System.IO.Stream dest, object value, System.Type type, ProtoBuf.PrefixStyle style, int fieldNumber, ProtoBuf.SerializationContext context) Line 467 + 0x24 bytes C#
protobuf-net.dll!ProtoBuf.Meta.TypeModel.SerializeWithLengthPrefix(System.IO.Stream dest, object value, System.Type type, ProtoBuf.PrefixStyle style, int fieldNumber) Line 435 + 0x32 bytes    C#

我使用rev 424.

我做错了什么?

谢谢。

编辑

我什么都不懂。如果我把Base<T>也变成非泛型,它就行不通了。我一定是漏掉了一些非常基本的东西。

EDIT2

调试代码发现,基类型属性的字段号与派生类型的字段号收集在同一个列表中。由此我推断,继承工作的唯一方式是使用代理。至少在第424版

.AddSubType(1, typeof(FlowFolder)); vs [DataMember(Order = 1)]

用于标识子类型的字段号不得与同一类型上的任何已定义字段冲突。只需使用一个与不冲突的数字。冲突只适用于类型—它不必在子类型中是唯一的;例如,.AddSubType(8, typeof(FlowFolder));就可以,FlowFolder是否有"字段8"并不重要。

由此我推断,继承工作的唯一方式是使用代理。

我不明白这是怎么回事....?

最新更新