protobu.net继承:派生类隐藏基类属性

本文关键字:隐藏 基类 属性 派生 net 继承 protobu | 更新日期: 2023-09-27 18:16:56

protobuf-net proto2 c#

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

我希望序列化一个基类实例并将其反序列化为派生类型:

[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'发生在dll,但未在用户代码中处理其他信息:无法强制转换类型的对象'BaseClass'转换为'DerivedClass'。

为什么protobuf-net试图将BaseClass转换为DerivedClass ?

难道protobuf-net不应该按照DerivedClass中的原型注释直接将消息反序列化到DerivedClass吗?

也隐藏BaseClass.IntProperty也隐藏其ProtoMember注释?因此允许在DerivedClass ?

中重新定义proto index 1

编辑添加额外信息:

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

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

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

进一步,如果我反序列化为object类型的引用(而不是DerivedClass),则底层类型是BaseClass。这解释了强制类型转换异常,但是提出了一个问题:为什么ProtoBuf.Serializer.Deserialize<DerivedClass>()反序列化为BaseClass类型的对象?

protobu.net继承:派生类隐藏基类属性

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