如何定义一个通用的基类的protobuf网模式? [英] How to define the protobuf-net model with a generic base class?

查看:834
本文介绍了如何定义一个通用的基类的protobuf网模式?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

由于这些类型:

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

我得到这个异​​常:

I get this exception:

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:\Work\protobuf-net-v2\protobuf-net\Serializers\TypeSerializer.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#

我使用转424。

I am using rev 424.

我是什么做错了吗?

感谢。

修改

我什么都不懂。如果我做它不工作基地&LT; T&GT; 非泛型类型为好。我必须失去了一些东西真的很基本的位置。

I do not understand anything. It does not work if I make Base<T> a non generic type as well. I must be missing something really basic here.

EDIT2

调试code揭示的基本类型的特性以相同的列表派生类型的场数的场数。从我推断,对于继承工作的唯一方法是使用代用品。至少在修订版424。

Debugging the code reveals that field numbers of the base type properties are collected in the same list with the field numbers of the derived types. From that I deduce that the only way for the inheritance to work is with surrogates. At least in revision 424.

推荐答案

.AddSubType(1的typeof(FlowFolder)); VS [数据成员(ORDER = 1)]

用于识别一个子类型不能与在该相同类型的任何定义字段冲突的场数。刚刚的使用了一些不冲突的。冲突仅适用于该类型的 - 它不必是其中子类型独特;例如, .AddSubType(8的typeof(FlowFolder)); 就可以了,它会不会也罢 FlowFolder 有一个场8。

The field-number used to identify a sub-type must not conflict with any defined fields on that same type. Just use a number that doesn't conflict. The conflict only applies to that type - it doesn't have to be unique among the sub-types; for example, .AddSubType(8, typeof(FlowFolder)); would be fine, and it would not matter whether FlowFolder had a "field 8".

这是我推断的继承工作的唯一方法是使用代用品。

From that I deduce that the only way for the inheritance to work is with surrogates.

我看不出下面....?

I don't see how that follows....?

这篇关于如何定义一个通用的基类的protobuf网模式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆