什么是WriteMessage API?如何用ProtoWriter.State序列化消息?
解决方案
你要找的WriteMessage API 是ProtoWriter.State提供的带委托参数的重载,无需额外实现ISerializer,直接将嵌套消息的写入逻辑内联传入即可,完全可以替代废弃的StartSubItem/EndSubItem组合。
写入嵌套消息示例
// state 为当前父消息的 ProtoWriter.State 实例 // 示例:写入字段号为 1 的嵌套消息,嵌套消息内部包含字段2的int32值、字段3的string值 state.WriteMessage( fieldNumber: 1, state: null, // 可传入自定义状态对象,无额外状态直接传null即可 (writerState, userState) => { // 此处直接写嵌套消息的所有内部字段,逻辑和写顶层消息完全一致 writerState.WriteInt32(2, 1234); writerState.WriteString(3, "嵌套消息内容"); // 其他字段写入逻辑... });
该方法内部已经封装了子消息长度计算、前缀写入、不同写入器的兼容性适配逻辑,不需要你手动处理子项令牌或者长度写入,也避开了废弃API的兼容性问题。
对应读取嵌套消息的API用法
读取侧也有配套的ReadMessage委托重载,用法和写入对应:
// 读取字段号为1的嵌套消息,返回内部字段解析结果 var nestedData = state.ReadMessage( state: null, (readerState, userState) => { int intVal = default; string strVal = default; while (readerState.ReadNextField(out var fieldNumber)) { switch (fieldNumber) { case 2: intVal = readerState.ReadInt32(); break; case 3: strVal = readerState.ReadString(); break; default: readerState.SkipField(); break; } } return (intVal, strVal); });
注意事项
不要自己手动实现StartSubItem/EndSubItem的逻辑,除了长度写入外,该类方法内部还处理了分组编码兼容、状态校验、缓冲区预分配等逻辑,自行实现很容易出现兼容问题或者序列化结果不符合protobuf规范的情况。
内容的提问来源于stack exchange,提问作者enzi
相关产品推荐
相关产品推荐

