protobuf-netinheritance
Marc在stackoverflow上提到,在protobuf-net的v2中可以使用ProtoInclude属性(或类似方法)来序列化/反序列化类层次结构,而无需在基类中指定每个子类型。 这实现了吗? 我们有一个可以在外部库中派生的插件接口,因此无法知道派生类型是什么。 我们可以在类型之间保持唯一的编号,但我在网上找不到任何示例,缺少使用ProtoInclude属性,需要指定子类型。
如果我不知道子类是什么,我将如何使用protobuf-net实现inheritance?
如果你不能在属性中指定子类型(因为它在编译时是未知的)你有2个选项(两个选项都只适用于“v2”,可用作beta):
- 使用
RuntimeTypeModel
,而不是静态的Serializer
方法(现在只是RuntimeTypeModel.Default
的快捷方式); 告诉模型inheritance(下面的例子) - 将
DynamicType = true
添加到相关的[ProtoMember(...)]
第二个不是非常纯粹的protobuf – 它嵌入类型信息,我不喜欢,但人们只是一直要求。 第一个是我的首选。 要在运行时添加子类型:
var model = TypeModel.Create(); var type = model.Add(typeof(YourBaseType), true); var subTypeA = model.Add(typeof(SomeSubType), true); var subTypeB = model.Add(typeof(SomeOtherSubType), true); type.AddSubType(4, typeof(SomeSubType)); type.AddSubType(5, typeof(SomeOtherSubType));
上面的true
表示“使用常规规则自动添加成员属性” – 您也可以控制它,并根据需要手动指定属性(等)。
请注意, TypeModel
应该被缓存并重新使用(不是每个需要序列化的对象创建的),因为它包含一些“emit”代码来生成方法。 重新使用它会更快,并且需要更少的内存。 类型模型是线程安全的,可用于在不同线程上并发地序列化/反序列化多个流。
为了进一步扩展Marc的答案,特别是处理RuntimeTypeModel
,这是编写它的一种方法:
RuntimeTypeModel.Default[typeof(BaseClass)].AddSubType(20, typeof(DerivedClass));
如果您有更多来自派生类的类,请像这样链接它们
RuntimeTypeModel.Default[typeof(DerivedClass)].AddSubType(20, typeof(DerivedFromDerivedClass ));
等等。
然后,您可以像使用protobuf-net一样使用Serializer.Serialize(file,object)
。
这适用于项目和命名空间。
通过添加辅助扩展方法:
public static class RuntimeTypeModelExt { public static MetaType Add(this RuntimeTypeModel model) { var publicFields = typeof(T).GetFields().Select(x => x.Name).ToArray(); return model.Add(typeof(T), false).Add(publicFields); } }
您可以简化子类型注册,如下所示:
private static RuntimeTypeModel CreateModel() { var model = TypeModel.Create(); model.Add(); model.Add(); model.Add() .AddSubType(101, model.Add().Type) .AddSubType(102, model.Add().Type) .AddSubType(103, model.Add().Type); return model; }
- 与Model和ViewModel混淆
- ASP.net MVC – 我应该使用ViewModel中的AutoMapper到Entity Framework实体吗?
- 如何使用SharpCompress的’BZip2Stream来压缩字符串?
- 知道Winforms TextBox中插入符号的点位置?
- 排除通用约束中的类型(可能?)
- Stored Proc返回一个Cursor,如何在C#中使用OLEDB来处理它
- Nhibernate Session 01的夏天,为什么我得到NHibernate.Bytecode.ProxyFactoryFactoryNotConfiguredException?
- 通过SkyDrive API将文件上传到skydrive
- 如何添加通用dependency injection