С учетом этих типов:
[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#
Я использую Rev 424.
Что я делаю не так?
Спасибо.
EDIT
Я ничего не понимаю. Это не сработает, если я сделаю Base<T>
также не универсальным типом. Я, должно быть, упускаю что-то действительно простое здесь.
EDIT2
Отладка кода показывает, что номера полей свойств базового типа собираются в одном списке с номерами полей производных типов. Из этого я делаю вывод, что единственный способ получения наследства - суррогаты. По крайней мере, в редакции 424.