[英]protobuf - serialization using protobuf-net with inheritance
序列化时获取“意外子类型”。
var model = RuntimeTypeModel.Create();
var baseType = model.Add(typeof(BaseClass), true, CompatibilityLevel.Level300);
var child = baseType.AddSubType(10, typeof(ChildOfBase));
child.AddSubType(20, typeof(GrandChildToBase));
using (var stream = new MemoryStream())
{
model.Serialize(stream, grandChildInstance); //ERROR : Unexpected sub type GrandChildToBase
}
获取“意外的子类型 GrandChildToBase” 注意:虽然我将 CompatLevel 设置为 300,但默认为 200。我使用的是 3.0.101 版
我不想在 BaseClass 上使用“ProtoInclude”。 (我所有的类都是通过 nuget 包独立分发的,并且在基类中断中有子类的知识)
编辑 1序列化现在正在运行! (感谢 Marc Gravell)但是,反序列化不是(获取“无法将 BaseClass 类型的对象强制转换为 GrandChildToBase”)。
var model = RuntimeTypeModel.Create();
model.DefaultCompatibilityLevel = CompatibilityLevel.Level300;
var baseType = model.Add(typeof(BaseClass));
var childType = model.Add(typeof(ChildOfBase));
model.Add(typeof(GrandChildToBase)); // don't need to capture result of this one
baseType.AddSubType(10, typeof(ChildOfBase));
childType.AddSubType(20, typeof(GrandChildToBase));
byte[] result = null;
using (var stream = new MemoryStream())
{
GrandChildToBase grandChildInstance = new();
model.Serialize(stream, grandChildInstance);
result = stream.ToArray();
}
using (var stream = new MemoryStream(result))
{
var payloadObj = Serializer.Deserialize<GrandChildToBase>(stream); ***//ERROR: "Unable to cast object of type BaseClass to GrandChildToBase"***
}
编辑 2根据@Marc Gravell 的澄清,我需要使用自定义“模型”而不是“默认”序列化程序。
这里的错误是AddSubType
API 用于链式构建器使用,并有效地返回您传入的相同对象- 或者特别是: AddSubType
的结果不是表示子类型的MetaType
; 你可以通过以下方式看到:
var child = baseType.AddSubType(10, typeof(ChildOfBase));
Console.WriteLine(ReferenceEquals(child, baseType)); // outputs True
这意味着当你做
child.AddSubType(20, typeof(GrandChildToBase));
你有效地将GrandChildToBase
添加到BaseClass
,而不是ChildOfBase
。
我承认图书馆应该在.AddSubType(20, typeof(GrandChildToBase))
步骤中清楚地告诉你这一点! 我会检查我们是否可以在那里添加断言。
然而! 要修复代码:
var model = RuntimeTypeModel.Create();
model.DefaultCompatibilityLevel = CompatibilityLevel.Level300;
var baseType = model.Add(typeof(BaseClass));
var childType = model.Add(typeof(ChildOfBase));
model.Add(typeof(GrandChildToBase)); // don't need to capture result of this one
baseType.AddSubType(10, typeof(ChildOfBase));
childType.AddSubType(20, typeof(GrandChildToBase));
using (var stream = new MemoryStream())
{
GrandChildToBase grandChildInstance = new();
model.Serialize(stream, grandChildInstance); //ERROR : Unexpected sub type GrandChildToBase
}
附带说明: 10
对20
- 这些并不相互冲突,因为它们(现在)应用于层次结构的不同级别; 如果您愿意,它们都可以是10
或任何其他数字。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.