Protobuf-net RuntimeTypeModel 不序列化基类的成员

Posted

技术标签:

【中文标题】Protobuf-net RuntimeTypeModel 不序列化基类的成员【英文标题】:Protobuf-net RuntimeTypeModel not serializing members of base class 【发布时间】:2012-05-01 16:06:55 【问题描述】:

假设我有以下基类:

[DataContract]
[Serializable]
public abstract class DimensionEntity

    [DataMember(Order = 1)]
    private readonly Date effectiveDatespan;
    ...

还有以下派生类:

[DataContract]
[Serializable]
public class ClearingSite : DimensionEntity

    [DataMember(Order = 1)]
    private readonly string code;
    ...

当我按如下方式序列化ClearingSite 的实例时:

        model.Add(typeof(ClearingSite), true);
        model.Serialize(ms, clearingSite);

我可以看到只有ClearingSitecode成员被序列化了;基类'effectiveDatespan 成员的值未序列化。

两个音符:

    可以看到添加的ProtoBuf.Meta.MetaTypeBaseType成员设置为null,导致effectiveDatespan成员没有被序列化;相反,如果我编译模型,则其 BaseType 成员被正确设置为 DimensionEntity(尽管稍后它会失败,因为成员是 private readonly,因此编译模型无法访问); 当然我可以将ClearingSite 声明为DimensionEntity 的已知类型,但我不明白为什么需要这样做:我没有序列化DimensionEntity,我正在序列化(和反序列化) 一个ClearingSite,此外,如果我正在序列化一个ClearingSiteDataContractSerializer 不需要我将KnownType 添加到DimensionEntity

从 Marc 的其他答案看来,Protobuf 似乎需要 KnownType(或 ProtoInclude)属性才能获得“最重要的字段编号”(引用),但这似乎不是情况下,CompiledModel 在没有ProtoInclude 的情况下完全可以正常工作。

请注意,我正在努力仅使用 System.Runtime.Serialization 属性,因为我试图让我的对象模型不知道未来的序列化程序。

【问题讨论】:

【参考方案1】:

ProtoInclude 或等效的,绝对是必需的。如果编译后的版本发生了奇怪的事情,那么这是一个错误,我可以调查。

如果您不想为您的类型添加非 BCL 属性,可以在运行时完成:

RuntimeTypeModel.Default[typeof(BaseType)]
    .AddSubClass(.....);

(或类似的东西 - 我不在电脑旁)

【讨论】:

谢谢马克。如果一个人实现了一个辅助函数,在将类型 T 添加到模型时会访问从 Tobject 的层次结构 path 并且对于每个类型 Ti 标记为DataContract 会自动 Add(typeof(Ti)).AddSubClass(T)? @Gabriele 我对“自动”的唯一问题是 数字 很重要,您需要能够可靠地获得 相同的数字 将来,即使在系统中添加了额外的类型,并且已经重命名了。如果你能做到:很好。

以上是关于Protobuf-net RuntimeTypeModel 不序列化基类的成员的主要内容,如果未能解决你的问题,请参考以下文章

Protobuf-net:嵌套的 IEnumerable 对象

用于继承的 Protobuf-net .proto 文件生成

使用protobuf-net继承时如何选择字段号?

带有 Protobuf-net 的端点行为配置 WCF

Protobuf-net.Grpc 服务契约继承

protobuf-net:如何注释派生类型的属性?