序列化对象,将接口作为消息包中的属性类型
本文关键字:包中 消息 属性 类型 对象 接口 序列化 | 更新日期: 2023-09-27 18:33:10
我正在尝试使用 MessagePack 序列化具有接口类型属性的对象。当我调用Pack
时,它会抛出SerializationException
,说没有为接口定义序列化程序。
代码示例:
namespace ConsoleApplication1
{
// interfaces and classes declaration
public interface IDummyInterface { }
public class DummyObject : IDummyInterface
{
public string Value { get; set; }
}
public class SmartObject
{
public string Name { get; set; }
IDummyInterface DummyOne { get; set; }
}
// in main
var mySmartObject = new SmartObject() { Name = "Yosy", DummyOne = new DummyObject() { Value = "Value"} };
using(var stream = new MemoryStream())
{
var serializer = MessagePackSerializer.Create<SmartObject>();
serializer.Pack(mySmartObject, stream); // => This code throws the exception
}
}
我可以告诉 MessagePack 哪个序列化程序用于 IDummyInterface 并告诉它充当 DummyObject 吗?
在我看来,
您正在使用msgpack-cli。要使其工作,基本上有两种方法可以做到这一点。
1. 使用MessagePackKnownTypeAttribute
这个简单明了。
public class SmartObject
{
public string Name { get; set; }
[MessagePackKnownType("d", typeof(DummyObject))]
public IDummyInterface DummyOne { get; set; } // Need to make this property public
}
2. 实现自定义序列化程序
如果你想要一个干净的模型类而不引用MsgPack
库,你可以执行以下操作,但你需要找到一种方法来序列化/反序列化SmartObject
(有效地(。
public class SmartObjectSerializer : MessagePackSerializer<SmartObject>
{
public SmartObjectSerializer(SerializationContext ownerContext) : base(ownerContext)
{
}
protected override void PackToCore(Packer packer, SmartObject objectTree)
{
var str = ToString(objectTree); // TODO: Just an example
packer.Pack(str);
}
protected override SmartObject UnpackFromCore(Unpacker unpacker)
{
var str = unpacker.LastReadData.AsStringUtf8(); // TODO: Just an example
return new SmartObject
{
// TODO: Initialize based on str value
};
}
}
// In main
var context = new SerializationContext();
context.Serializers.RegisterOverride(new SmartObjectSerializer(context));
var serializer = MessagePackSerializer.Get<SmartObject>(context);
// The rest is the same
您可能有兴趣查看一些示例代码。
- 自定义序列化程序
- 多态性