【发布时间】:2012-02-14 12:53:08
【问题描述】:
我假设它会查看您的模型并以某种方式准备好东西,这样您的前几次序列化就不会减慢。如果我的消息传递模型有一个带有子类的消息类怎么办?将我的父类放在类型参数中是否也会为所有子类做好准备?
【问题讨论】:
-
哦,我还应该注意:如果您想要绝对最小的旋转,您可以将序列化程序预编译为程序集 (dll),并在您的主项目中引用它...
标签: c# serialization protobuf-net
我假设它会查看您的模型并以某种方式准备好东西,这样您的前几次序列化就不会减慢。如果我的消息传递模型有一个带有子类的消息类怎么办?将我的父类放在类型参数中是否也会为所有子类做好准备?
【问题讨论】:
标签: c# serialization protobuf-net
(此答案假定 protobuf-net v2)
如果您的意思是Serializer.PrepareSerializer<T>(),那么它肯定会检查所有子类型,因此将为它们准备好类型模型(意思是:它将找出哪些字段/属性等需要序列化)。它将预编译(即 IL-emit)parent 类的代码,但(查看代码)不是专门针对派生类型的。如果无人看管,派生类型将在第一次需要时自行编译。我想!如果你真的想要,我可以做一个彻底的检查。
但是,如果您使用RuntimeTypeModel.Default.CompileInPlace(),它会构建整个模型 - 已知的一切都已准备好。当然,这就留下了必须先告诉模型它们的困境;p
我会仔细检查一下子类型序列化程序在什么时候准备好,以确保确定。级联它们可能确实有意义。
更新:
看起来它确实级联到派生类型,但没有级联到父类型(如果有的话):
[Test]
public void CheckTypeSpecificCompileInPlaceCascadesToBaseAndChildTypes()
{
var model = TypeModel.Create();
model[typeof(B)].CompileInPlace();
Assert.IsTrue(model.IsPrepared(typeof(D)), "D"); // sub-sub-type
Assert.IsTrue(model.IsPrepared(typeof(C)), "C"); // sub-type
Assert.IsTrue(model.IsPrepared(typeof(B)), "B"); // self
Assert.IsTrue(model.IsPrepared(typeof(A)), "A"); // base-type
}
[Test]
public void CheckGlobalCompileInPlaceCascadesToBaseAndChildTypes()
{
var model = TypeModel.Create();
model.Add(typeof (B), true); // give the model a clue!
model.CompileInPlace();
Assert.IsTrue(model.IsPrepared(typeof(D)), "D"); // sub-sub-type
Assert.IsTrue(model.IsPrepared(typeof(C)), "C"); // sub-type
Assert.IsTrue(model.IsPrepared(typeof(B)), "B"); // self
Assert.IsTrue(model.IsPrepared(typeof(A)), "A"); // base-type
}
这里,第二个测试通过了;第一个测试引用“A”失败 - 因此子类型(“C”和“D”)已完全编译。由于基本类型仍将按需编译,因此可能按原样进行,但如果有用的话,我可能会将其纳入祖先类型。
(IsPrepared方法只存在于我的本地副本中)
【讨论】: