为什么有些内置类型在我编译 typeModel 时不起作用?
Why don't some Built-in types work when I compile typeModel?
当我编译 Type 模型字典时停止工作。
[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 中,或者还有其他一些方法?
顺便说一句,当我想预编译序列化程序时,我不明白为什么我必须制作所有内容 public?
是的,当您创建自己的类型模型时,您需要提前告诉它要包含什么 - 否则它不知道要支持什么。理想情况下,这包括您将序列化为根类型的所有类型,因此:如果您要序列化字典:告诉它。在内部,protobuf-net v2 实际上并没有特殊情况的字典——它将它们视为一个类似列表的类型序列 (KeyValuePair<TKey, TValue>
),恰好看起来很像它可以猜测的类型"tuple"; protobuf-net v3 确实知道更多关于字典的知识,但是......你还是提前告诉它更好。
BTW I don't get why do I have to make everything public when I want to precompile serializers?
有两种类型的预编译;也许你 实际上 只是想要 CompileInPlace()
(而不是 Compile()
),它保留了现有的 RuntimeTypeModel
,但在幕后使用 IL-emit 来创建轻量级垫片方法来完成这项工作;使用这种方法时,可以绕过可访问性验证检查,允许我访问非 public 的任何内容;但是,当您使用 Compile()
时,您是在真实程序集中创建真实类型(只是:在内存中),而当您使用 that 时:您 不能 绕过可访问性检查(以及其他一些验证检查);这意味着我遵守与您在 C# 编译器中相同的规则:如果它不是 public,我就不能碰它。
当我编译 Type 模型字典时停止工作。
[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 中,或者还有其他一些方法?
顺便说一句,当我想预编译序列化程序时,我不明白为什么我必须制作所有内容 public?
是的,当您创建自己的类型模型时,您需要提前告诉它要包含什么 - 否则它不知道要支持什么。理想情况下,这包括您将序列化为根类型的所有类型,因此:如果您要序列化字典:告诉它。在内部,protobuf-net v2 实际上并没有特殊情况的字典——它将它们视为一个类似列表的类型序列 (KeyValuePair<TKey, TValue>
),恰好看起来很像它可以猜测的类型"tuple"; protobuf-net v3 确实知道更多关于字典的知识,但是......你还是提前告诉它更好。
BTW I don't get why do I have to make everything public when I want to precompile serializers?
有两种类型的预编译;也许你 实际上 只是想要 CompileInPlace()
(而不是 Compile()
),它保留了现有的 RuntimeTypeModel
,但在幕后使用 IL-emit 来创建轻量级垫片方法来完成这项工作;使用这种方法时,可以绕过可访问性验证检查,允许我访问非 public 的任何内容;但是,当您使用 Compile()
时,您是在真实程序集中创建真实类型(只是:在内存中),而当您使用 that 时:您 不能 绕过可访问性检查(以及其他一些验证检查);这意味着我遵守与您在 C# 编译器中相同的规则:如果它不是 public,我就不能碰它。