protobuf-net继承:派生类隐藏基类属性

时间:2016-11-08 07:13:13

标签: c# inheritance override virtual protobuf-net

protobuf-net proto2 c#

我有一个派生类,它通过隐藏相同名称的相应基类属性来重新定义类型。

我希望序列化一个基类实例并反序列化为derived-type:

[ProtoBuf.ProtoContract(Name=@"BaseClassProto")]
[ProtoBuf.ProtoInclude(typeof(DerivedClass), 1000)]
public partial class BaseClass {
  [ProtoBuf.ProtoMember(1, IsRequired = false, Name = @"MyProperty", DataFormat = ProtoBuf.DataFormat.TwosComplement)] 
  public int MyProperty { get; set; }
}

[ProtoBuf.ProtoContract(Name=@"DerivedClassProto")] 
public partial class DerivedClass : BaseClass {
  [ProtoBuf.ProtoMember(1, IsRequired = false, Name = @"MyProperty", DataFormat = ProtoBuf.DataFormat.TwosComplement)] 
  public new MyEnum MyProperty { get; set; }
  }
}

public class Test {
  var baseObject = new BaseClass{ TestString = "TestBaseObject", TestInt = 1 };

  DerivedClass derivedObject;
  using (var stream = new MemoryStream())
  {
    ProtoBuf.Serializer.Serialize(stream, baseObject);
    Debug.WriteLine(stream.Length);
    stream.Seek(0, SeekOrigin.Begin);
    derivedObject = ProtoBuf.Serializer.Deserialize<DerivedClass>(stream);
  }
}
  

发生了'System.InvalidCastException'类型的异常   protobuf-net.dll但未在用户代码中处理   附加信息:无法转换类型的对象   'BaseClass'键入'DerivedClass'。

为什么protobuf-net会尝试将BaseClass投放到DerivedClass

根据protobuf-net中的原始注释,DerivedClass不应该直接将邮件反序列化到DerivedClass吗?

隐藏BaseClass.IntProperty也会隐藏其ProtoMember注释吗?从而允许在proto index 1

中重新定义DerivedClass

编辑添加其他信息:

尝试最小可行的测试用例,即使我重新定义DerivedClass尽可能简单:

[ProtoBuf.ProtoContract(Name=@"DerivedClassProto")] 
public partial class DerivedClass : BaseClass {
}

我仍然发现序列化BaseClass /反序列化DerivedClass会抛出相同的System.InvalidCastException

此外,如果我反序列化为object类型(而不是DerivedClass)的引用,则基础类型为BaseClass。这解释了强制转换异常,但是询问为什么ProtoBuf.Serializer.Deserialize<DerivedClass>()反序列化为BaseClass类型的对象?

1 个答案:

答案 0 :(得分:1)

protobuf-net中不同级别的层次结构是.proto术语中的单独消息。子类的标记独立于基类中的标记。重用标签不是级别之间的概念。我很惊讶所显示的代码实际上是有效的,因为它似乎在一个级别中使用标记1两次(一次用于子类型,一次用于属性 - 两者都在MyBaseType)。这可能导致混淆错误。