You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用MessagePack序列化第三方库中无法标记特性的对象?

MessagePack-CSharp 序列化第三方无源码对象的替代方案

MessagePack-CSharp确实支持类似Protobuf代理(Surrogate)的实现,无需修改第三方类的源码,核心思路是通过**自定义格式化器(IMessagePackFormatter)**完成对象与代理类的转换映射。

实现步骤

  1. 定义代理类:创建与第三方类属性匹配的代理类,用于承载序列化/反序列化的数据:
public class Point3DSurrogate
{
    public float X { get; set; }
    public float Y { get; set; }
    public float Z { get; set; }
}
  1. 实现自定义格式化器:实现IMessagePackFormatter<Point3D>接口,在序列化时将第三方对象转成代理对象,反序列化时再转换回第三方对象:
public class Point3DFormatter : IMessagePackFormatter<Point3D>
{
    public void Serialize(ref MessagePackWriter writer, Point3D value, MessagePackSerializerOptions options)
    {
        var surrogate = new Point3DSurrogate
        {
            X = value.X,
            Y = value.Y,
            Z = value.Z
        };
        options.Serializer.Serialize(ref writer, surrogate);
    }

    public Point3D Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options)
    {
        var surrogate = options.Serializer.Deserialize<Point3DSurrogate>(ref reader);
        return new Point3D(surrogate.X, surrogate.Y, surrogate.Z);
    }
}
  1. 注册格式化器并使用:把自定义格式化器添加到序列化选项中,后续序列化/反序列化指定该选项即可:
// 配置序列化选项,注册自定义格式化器
var serializeOptions = MessagePackSerializerOptions.Standard
    .WithFormatter(new Point3DFormatter());

// 序列化第三方对象
var pp = new Point3D(0, 0, 0);
byte[] bytes = MessagePackSerializer.Serialize(pp, serializeOptions);

// 反序列化回第三方对象
var deserializedPoint = MessagePackSerializer.Deserialize<Point3D>(bytes, serializeOptions);

额外说明

如果需要批量处理多个第三方类型,也可以通过自定义ContractResolver扩展,但上述自定义格式化器的方式最贴近Protobuf中Surrogate的使用逻辑,直接针对目标类型做一对一的转换映射,逻辑清晰且易于维护。

内容的提问来源于stack exchange,提问作者niks

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 05:30:55