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);
我可以看到只有ClearingSite
的code
成员被序列化了;基类'effectiveDatespan
成员的值未序列化。
两个音符:
-
可以看到添加的
ProtoBuf.Meta.MetaType
的BaseType
成员设置为null
,导致effectiveDatespan
成员没有被序列化;相反,如果我编译模型,则其 BaseType
成员被正确设置为 DimensionEntity
(尽管稍后它会失败,因为成员是 private readonly
,因此编译模型无法访问);
当然我可以将ClearingSite
声明为DimensionEntity
的已知类型,但我不明白为什么需要这样做:我没有序列化DimensionEntity
,我正在序列化(和反序列化) 一个ClearingSite
,此外,如果我正在序列化一个ClearingSite
,DataContractSerializer
不需要我将KnownType
添加到DimensionEntity
。
从 Marc 的其他答案看来,Protobuf 似乎需要 KnownType
(或 ProtoInclude
)属性才能获得“最重要的字段编号”(引用),但这似乎不是情况下,CompiledModel
在没有ProtoInclude
的情况下完全可以正常工作。
请注意,我正在努力仅使用 System.Runtime.Serialization
属性,因为我试图让我的对象模型不知道未来的序列化程序。
【问题讨论】:
【参考方案1】:ProtoInclude 或等效的,绝对是必需的。如果编译后的版本发生了奇怪的事情,那么这是一个错误,我可以调查。
如果您不想为您的类型添加非 BCL 属性,可以在运行时完成:
RuntimeTypeModel.Default[typeof(BaseType)]
.AddSubClass(.....);
(或类似的东西 - 我不在电脑旁)
【讨论】:
谢谢马克。如果一个人实现了一个辅助函数,在将类型T
添加到模型时会访问从 T
到 object
的层次结构 path 并且对于每个类型 Ti
标记为DataContract
会自动 Add(typeof(Ti)).AddSubClass(T)
?
@Gabriele 我对“自动”的唯一问题是 数字 很重要,您需要能够可靠地获得 相同的数字 将来,即使在系统中添加了额外的类型,并且已经重命名了。如果你能做到:很好。以上是关于Protobuf-net RuntimeTypeModel 不序列化基类的成员的主要内容,如果未能解决你的问题,请参考以下文章
Protobuf-net:嵌套的 IEnumerable 对象