序列化对象,将接口作为消息包中的属性类型

本文关键字:包中 消息 属性 类型 对象 接口 序列化 | 更新日期: 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
您可能

有兴趣查看一些示例代码。

  • 自定义序列化程序
  • 多态性