c# - 在 MessagePack 中将具有接口(interface)作为属性类型的对象序列化

标签 c# serialization msgpack

我正在尝试使用 MessagePack 序列化具有接口(interface)类型属性的对象。当我调用 Pack , 它抛出 SerializationException这表示没有为接口(interface)定义序列化程序。
代码示例:

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
您可能有兴趣查看一些示例代码。
  • CustomSerializer
  • Polymorphism
  • 关于c# - 在 MessagePack 中将具有接口(interface)作为属性类型的对象序列化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19080982/

    相关文章:

    c++ - 使用 QDataStream 序列化自定义类导致 C2679 错误

    java - MsgPack 在 Android 中序列化一个 JsonObject

    golang msgpack 自定义编码

    c# - 如何在 C# 中计算 OneDrive XOrHash

    java - 序列化对象的文件扩展名

    c# - 不同时间事件执行不同代码

    java - 序列化ObjectInputStream无效流 header : 00000000

    java - 如何使用 Java 将 INT32 打包到我的 MessagePack 中?

    c# - 异步在 ASP.NET Web 应用程序中如何工作?

    c# - Code First 默认 DateTime 不工作