在我的应用程序中,我正在使用protobuf-net对通过线路发送的消息进行序列化。每条消息都有一个标题信息的键值对列表。
然而,我遇到了一个例外,我已经能够用一个非常简单的例子重现它:
[TestFixture]
public class SerializationTests
{
[ProtoContract]
public class MyType
{
[ProtoMember(1, DynamicType = true)]
public object Property { get; set; }
}
[Test]
public void SerializationTest()
{
var myType = new MyType {Property = DateTime.UtcNow.ToBinary()};
Action action = () => myType.Serialize();
action.ShouldNotThrow();
}
}
public static byte[] Serialize<T>(this T itemToSerialize)
{
using (MemoryStream ms = new MemoryStream())
{
ProtoBuf.Serializer.Serialize(ms, itemToSerialize);
byte[] objectArray = ms.ToArray();
return objectArray;
}
}
此测试当前失败,但出现异常:System.InvalidOperationException:“动态类型不是契约类型:Int64”。
该属性属于object类型,因此我可以在其中放入各种数据 - 因为这是标题信息。我试图避免使用多个标题列表,其中每个标题列表都是强类型的。
如果我将Property更改为long类型,则测试有效。如果我删除DynamicType = true,那么我得到一个异常,表明类型对象不存在序列化器。
由于测试在我更改属性类型时起作用,这似乎意味着DynamicType和long不能一起工作。
我目前正在使用r640(我相信这是NuGet的最新版本)。
答案 0 :(得分:2)
Dynamic type
的当前实现不支持基元。它只支持契约类型(其他类以某种方式定义为ProtoContract
)。
来自the wiki:
DynamicType - 使用类型存储其他类型信息(默认情况下,它包含AssemblyQualifiedName,尽管这可以由用户控制)。这使得序列化弱模型成为可能,即对象用于属性成员,但是目前这仅限于契约类型(不是原语),并且不适用于具有继承的类型(这些限制可能会在以后删除) 。与AsReference一样,它使用非常不同的布局格式