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

如何为含object属性的ChangeRecord类编写自定义protobuf-net序列化器

问题

我正尝试编写一个自定义protobuf-net序列化器,用于将object类型的属性序列化到传输流中。现有代码如下:

[ProtoContract(Serializer=typeof(ChangeRecordSerializer))]
public class ChangeRecord
{
   public object NewValue {get;set;}
}

目前我的实现进度如下:

public class ChangeRecordSerializer : ISerializer<ChangeRecord>
{
   public void Write(ref ProtoWriter.State state, ChangeRecord value)
   {
      state.WriteString(1, value.NewValue.GetType().FullName;
      // how to serialize value.NewValue???
   }

   public void Read(ref ProtoReader.State state, ChangeRecord value)
   {
      int num = 0;
      string typeName = null;
      while ((num = state.ReadFieldHeader()) > 0)
      {
         switch (num)
         {
            case 1:
               typeName = state.ReadString();
               break;

            case 2:
               var type = Type.GetType(typeName);
               // how to read value.NewValue???
               break;
         }
      }
   }

   public SerializerFeatures Features => SerializerFeatures.CategoryMessage | SerializerFeatures.WireTypeString;
}

请问如何实现上述代码中两处注释标记的逻辑?

解决方案

1. 实现Write方法中的序列化逻辑

先修正原代码的语法错误(GetType().FullName后缺少右括号),然后借助protobuf-net内置的Serializer.NonGeneric.Serialize方法,将NewValue序列到字段2中:

public void Write(ref ProtoWriter.State state, ChangeRecord value)
{
    // 写入类型全名到字段1
    state.WriteString(1, value.NewValue.GetType().FullName);
    // 序列化NewValue到字段2
    Serializer.NonGeneric.Serialize(ref state, 2, value.NewValue);
}

注意:自定义类型必须添加[ProtoContract]和[ProtoMember]属性才能正常序列化;int、string等系统内置类型无需额外配置,protobuf-net会自动处理。

2. 实现Read方法中的反序列化逻辑

使用Serializer.NonGeneric.Deserialize方法,根据读取到的类型全名获取Type后,反序列化字段2的数据并赋值给NewValue,同时建议添加未知字段跳过逻辑增强鲁棒性:

public void Read(ref ProtoReader.State state, ChangeRecord value)
{
    int num = 0;
    string typeName = null;
    while ((num = state.ReadFieldHeader()) > 0)
    {
        switch (num)
        {
            case 1:
                typeName = state.ReadString();
                break;

            case 2:
                var type = Type.GetType(typeName);
                // 反序列化字段2的数据到NewValue
                value.NewValue = Serializer.NonGeneric.Deserialize(type, ref state);
                break;
            default:
                // 跳过未知字段,避免解析失败
                state.SkipField();
                break;
        }
    }
}

额外提示:如果目标类型不在当前程序集或系统核心程序集中,建议用GetType().AssemblyQualifiedName替代FullName,确保Type.GetType能准确找到对应类型。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 11:17:46