本文介绍了Protobuf-net RuntimeTypeModel 不序列化基类的成员的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有以下基类:

[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 的一个实例时:

When I serialize an instance of ClearingSite as follows:

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

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

I can see that only the code member of ClearingSite is serialized; the value of the base class' effectiveDatespan member is not serialized.

两个注意事项:

  1. 可以看到添加的ProtoBuf.Meta.MetaTypeBaseType成员设置为null,导致effectiveDatespan 成员不被序列化;相反,如果我编译模型,它的 BaseType 成员被正确设置为 DimensionEntity(尽管它后来失败了,因为成员是 private readonly 和因此无法被编译模型访问);
  2. 当然,我可以将 ClearingSite 声明为 DimensionEntity 的已知类型,但我不明白为什么需要这样做:我没有序列化 DimensionEntity,我正在序列化(和反序列化)一个 ClearingSite,而且 DataContractSerializer 不需要我添加 KnownType> 到 DimensionEntity 如果我正在序列化一个 ClearingSite.
  1. I can see that the BaseType member of the added ProtoBuf.Meta.MetaType is set to null, causing the effectiveDatespan member to not be serialized; if I compile the model, instead, its BaseType member is correctly set to DimensionEntity (though it fails later on as the members are private readonly and thus not accessible by a compiled model);
  2. Of course I can declare ClearingSite as a known type of DimensionEntity, but I can't see why this would be required: I am not serializing a DimensionEntity, I'm serializing (and de-serializing) a ClearingSite, and furthermore the DataContractSerializer does not require me to add KnownType to DimensionEntity if I'm serializing a ClearingSite.

从 Marc 的其他答案来看,Protobuf 似乎需要 KnownType(或 ProtoInclude)属性才能获得所有重要的字段编号"(引用),但情况似乎并非如此,因为 CompiledModel 在没有 ProtoInclude 的情况下完全正常工作.

From other answers from Marc, it looks like Protobuf would require the KnownType (or ProtoInclude) attribute in order to get the "all-important field-number" (quote), but that seems to not be the case, as the CompiledModel works totally fine without ProtoInclude.

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

Note that I'm striving to use System.Runtime.Serialization attributes only, as I'm trying to keep my object model unaware of serializers down the road.

推荐答案

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

ProtoInclude, or an equivalent, is definitely required. If something is happening oddly with the compiled version, then that is a bug and I can investigate.

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

If you don't want to add non-BCL attributes to your type, this can be done at runtime:

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

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

(or somethig like that - I'm not at a PC)

这篇关于Protobuf-net RuntimeTypeModel 不序列化基类的成员的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-02 11:13