首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >protobuf-net继承

protobuf-net继承
EN

Stack Overflow用户
提问于 2011-06-06 11:24:10
回答 3查看 7.9K关注 0票数 13

Marc在stackoverflow上提到,在protobuf-net的v2中,可以使用ProtoInclude属性(或类似方法)来序列化/反序列化类层次结构,而不需要在基类中指定每个子类型。这已经实现了吗?我们有一个可以在外部库中派生的插件接口,所以没有办法知道派生类型是什么。虽然我们可以在类型之间保持唯一的编号,但我在网上找不到任何示例,除了使用ProtoInclude属性之外,它需要指定一个子类型。

如果我不知道子类型是什么,我该如何使用protobuf-net实现继承呢?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-06-06 13:33:49

如果你不能在属性中指定子类型(因为它在编译时是未知的),你有两个选择(这两个选择都只适用于"v2",测试版):

  1. 使用RuntimeTypeModel,而不是静态Serializer方法(现在只是RuntimeTypeModel.Default的快捷方式);告诉模型关于继承(下面的示例)
  2. DynamicType = true添加到有问题的[ProtoMember(...)] <代码>H29<代码>G210

第二个不是非常纯粹的protobuf -它嵌入了类型信息,我并不是很喜欢,但是人们只是一直在请求。第一个是我的首选。要在运行时添加子类型:

代码语言:javascript
复制
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“代码。重用它会更快,并且需要更少的内存。类型模型是线程安全的,可用于在不同线程上同时序列化/反序列化多个流。

票数 19
EN

Stack Overflow用户

发布于 2012-11-14 07:44:14

为了进一步扩展Marc的答案,特别是处理RuntimeTypeModel,这是一种编写它的方法:

代码语言:javascript
复制
RuntimeTypeModel.Default[typeof(BaseClass)].AddSubType(20, typeof(DerivedClass));

如果您有更多从派生类派生的类,请像这样将它们链接起来

代码语言:javascript
复制
RuntimeTypeModel.Default[typeof(DerivedClass)].AddSubType(20, typeof(DerivedFromDerivedClass ));

诸若此类。

然后,您可以使用Serializer.Serialize(file,object),就像您通常使用protobuf-net一样。

这可以跨项目和名称空间工作。

票数 5
EN

Stack Overflow用户

发布于 2013-09-24 17:46:35

通过添加helper扩展方法:

代码语言:javascript
复制
public static class RuntimeTypeModelExt
{
    public static MetaType Add<T>(this RuntimeTypeModel model)
    {
        var publicFields = typeof(T).GetFields().Select(x => x.Name).ToArray();
        return model.Add(typeof(T), false).Add(publicFields);
    }
}

您可以简化子类型注册,如下所示:

代码语言:javascript
复制
private static RuntimeTypeModel CreateModel()
{
    var model = TypeModel.Create();
    model.Add<ExportInfo>();
    model.Add<RegistrationInfo>();
    model.Add<FactorySetupInfo>()
        .AddSubType(101, model.Add<ServiceSetupInfo>().Type)
        .AddSubType(102, model.Add<GenericWrapperSetupInfo>().Type)
        .AddSubType(103, model.Add<DecoratorSetupInfo>().Type);
    return model;
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6247513

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档