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