2011-07-18 81 views
2

鉴于这些类型:如何用泛型基类定义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:\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

我在做什么错?

谢谢。

编辑

我什么都不懂。如果我使Base<T>也是非泛型类型,它也不起作用。我必须在这里错过一些非常基本的东西。

EDIT2

调试代码揭示的基本类型属性被收集在与派生类型的场数的相同列表的该字段的数字。从中我推断继承工作的唯一途径是代理人。至少在修订424

回答

3

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

使用的字段号码识别子类型不能与其他同类型的任何定义字段冲突。只需使用不冲突的号码。冲突仅适用于,类型为 - 在子类型中不必是唯一的;例如,.AddSubType(8, typeof(FlowFolder));会很好,FlowFolder是否有“字段8”也无关紧要。

从这我推断,继承工作的唯一途径是代理人。

我不明白如何......?

+0

我的不好,我想我不必关心子类型字段的数字。到现在为止,我只用继承来代替,并且在那里不存在这样的问题(因为代理实际上并不是从basee类型派生的)。无论如何,谢谢你清理它。 – mark