我是 Protobuf.net 的新手, 我们有很多类,它是与父类继承的,有时是多级继承的。 我们不能在任何地方添加 [ProtoIninclude()] 。 我不知道我们真的需要这个或任何可用的替代方式。 (同样如此 - 在派生类中我们可以提及基类的类型)。
我们还尝试仅在序列化时直接将其设置为
public static void RegisterTypesForObject(object obj)
{
int i = 100;
Type currentType = obj.GetType();
while (currentType != null && currentType.BaseType != typeof(object))
{
RuntimeTypeModel.Default[currentType.BaseType].AddSubType(i, currentType);
currentType = currentType.BaseType;
i++;
}
}
这个方法设置了它的父类和子类,但它只能工作一次。 如果我们尝试序列化一个类并第二次序列化不同的类,那么我们会收到错误 “一旦为 TrackingObject 生成序列化程序,就无法更改类型”。
您可以参考这里的代码 - link。
反序列化后我们应该保留所有值。
当反序列化器遇到基类型时,它需要知道要反序列化的具体类型。因此,如果我有
Base
、DerivedA
和 DerivedB
并序列化 Base objectToSerialize = new DerivedA()
,它将使用 protoIninclude Id 来知道它应该创建 DerivedA
而不是 DerivedB
。
这种方法并不是 Protobuf.net 独有的,System.text.json 的做法非常相似。另一方面,旧的 BinaryFormatterSerializer 本质上包含完整的类型名称,但这是一个主要的安全问题,因为您可以使反序列化器创建任意类型的对象!
如果您同时使用
DerivedA
和 DerivedB
调用示例代码,您将正确地收到错误,因为您告诉类型模型对两种类型使用相同的 id。
如果您仔细跟踪已用于每个基本类型的 ID,则可以动态生成 ID。但这不是我推荐的,除非你 100% 确定 id 永远不会引用另一种类型。我个人更喜欢传统的手动管理的序列化模型。或者,如果您致力于生成代码,也许可以将每组生成的类保留为单独的版本化模型,以确保反序列化能够正常工作。