当我编译类型时,模型字典停止工作。
[Test]
public void TestCompileSerialization()
{
var data = new Dictionary<int, int>();
data[1] = 1;
var typeModel = TypeModel.Create();
var compiledTypeModel = typeModel.Compile();
using (var memory = new MemoryStream())
{
compiledTypeModel.Serialize(memory, data);
}
}
此测试抛出
Type is not expected, and no contract can be inferred: System.Collections.Generic.KeyValuePair`2[[System.Int32, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.Int32, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]
我需要将我可能想要序列化的每个字典添加到TypeModel中吗?或者还有其他方法吗?
顺便说一句,我不明白为什么当我想预编译序列化程序时,我必须公开所有内容?
是的,当您创建自己的类型模型时,您需要提前告诉它要包含什么,否则它将不知道要支持什么。理想情况下,这包括所有将序列化为根类型的类型,因此:如果要序列化字典:请告诉它。在内部,protobuf-netv2实际上并不是特例字典——它将它们视为一个类型(KeyValuePair<TKey, TValue>
(的列表式序列,恰好看起来很像它可以猜测为"元组"的类型;protobuf net v3确实了解更多关于字典的信息,但是。。。你最好还是提前说出来。
BTW我不明白为什么当我想预编译序列化程序时,我必须公开所有内容?
有两种类型的预编译;也许您实际上只是想要CompileInPlace()
(而不是Compile()
(,它保留了现有的RuntimeTypeModel
,但在幕后使用IL来创建轻量级的填充方法来完成这项工作;当使用这种方法时,可以绕过可访问性验证检查,允许我访问非公共的任何内容;然而,当您使用Compile()
时,您正在真实程序集中创建真实类型(仅:在内存中(,并且当您执行时:您无法绕过可访问性检查(以及其他一些验证检查(;这意味着我要遵守和你在C#编译器中一样的规则:如果它不是公共的,我就不能碰它。