C#中数组ProtoBuf使用问题

embedded/2024/10/25 10:28:29/

使用 C# 类库 Google.Protobuf 包,进行协议定义,当给数组属性赋值默认值时,出现反序列化以后,数组长度翻倍,多的一部分在最前面,而且都是数组元素的默认值 

Code:

// 类定义
[ProtoContract]
public class ArrayClass
{[ProtoMember(1)]public int[] Array1 { get; set; } = new int[2];[ProtoMember(2)]public int[] Array1NoDefault { get; set; }[ProtoMember(3)]public int[] Array1Raw = new int[2];[ProtoContract]public class InnerClass{[ProtoMember(1)]public string Ele { get; set; }}[ProtoMember(4)]public InnerClass[] Array2 { get; set; } = new InnerClass[2];[ProtoMember(5)]public InnerClass[] Array2Raw = new InnerClass[2];
}// 操作如下
{var arrayClass = new ArrayClass();arrayClass.Array1NoDefault = new int[2];Array.Fill(arrayClass.Array1, 1);Array.Fill(arrayClass.Array1NoDefault, 1);Array.Fill(arrayClass.Array1Raw, 1);ArrayClass.InnerClass innerClass = new(){Ele = "2",}; Array.Fill(arrayClass.Array2, innerClass);Array.Fill(arrayClass.Array2Raw, innerClass);Log.Debug(JsonHelper.ToJson(arrayClass));var bytes = ProtobufHelper.ToBytes(arrayClass);var arrayClass1 = ProtobufHelper.FromBytes(typeof(ArrayClass), bytes);Log.Debug(JsonHelper.ToJson(arrayClass1));
}// Log.Debug输出如下:
/*
原类输出Json输出
{"Array1":[1,1],"Array1NoDefault":[1,1],"Array2":[{"Ele":"2"},{"Ele":"2"}],"Array1Raw":[1,1],"Array2Raw":[{"Ele":"2"},{"Ele":"2"}]}ProtoBuf后再反序列化Json输出
{"Array1":[0,0,1,1],"Array1NoDefault":[1,1],"Array2":[null,null,{"Ele":"2"},{"Ele":"2"}],"Array1Raw":[0,0,1,1],"Array2Raw":[null,null,{"Ele":"2"},{"Ele":"2"}]}
*///  可以发现 除了 Array1NoDefault其它 数组的长度增加了一倍,且全是数组元素的默认值

这个bug如果没有仔细观察会以为是逻辑代码的问题,解决办法就是,在定义数组时,不给默认值,用的时候再new, 就像例子中 Array1NoDefault  定义那样。


http://www.ppmy.cn/embedded/50284.html

相关文章

Redis内存数据库

Redis是一个开源的内存数据库,它可以用作缓存、数据库和消息中间件。Redis支持多种数据结构,包括字符串、哈希表、列表、集合、有序集合等,这使得它非常灵活且适用于多种用途。 以下是关于Redis的一些重要特点和功能: 内存存储&a…

Nginx负载均衡之动态更新upstream

Nginx 的配置是启动时一次性加载到内存中的,在实际的使用中,对 Nginx 服务器上游服务器组中节点的添加或移除仍需要重启或热加载 Nginx 进程。在 Nginx 的商业版本中,提供了 ngx_http_api_module 模块,可以通过 API 动态添加或移除…

【C++】内存管理

内存管理整理 1 释放内存 在C中,delete操作符的底层实现并不直接调用C语言中的free函数。尽管它们的目的都是为了释放动态分配的内存,但delete在C中有更多的语义和复杂性,因为它涉及到调用对象的析构函数。 以下是delete操作符在C中大致的…

dvadmin 调试问题

链接:django-vue3-admin: django-vue3-admin 是一套全部开源的快速开发平台,毫无保留给个人免费使用、团体授权使用。 django-vue3-admin 基于RBAC模型的权限控制的一整套基础开发平台,权限粒度达到列级别,前后端分离,…

kettle实时增量同步mysql数据

** 本文主要介绍运用kettle实时增量同步mysql数据 ** Debezium介绍 官网地址:https://debezium.io/documentation/ Debezium是一个开源项目,为捕获数据更改(Capture Data Change,CDC)提供了一个低延迟的流式处理平台,通过安装配置Debeziu…

楼顶气膜体育馆建设的关键问题解析—轻空间

随着城市化进程的加快和土地资源的日益紧张,楼顶气膜体育馆作为一种新兴的建筑形式备受关注。其轻盈美观、节省用地、施工便捷等特点,使其成为城市空间利用的理想选择。那么,在楼顶建设气膜体育馆有哪些关键问题需要考虑呢? 一、楼…

Shell 学习笔记 - 变量的删除、替换和替代 + 变量中的特殊符号

1.9 Shell 变量的删除、替换和替代 Linux 提供一些可以直接对变量进行操作的符号。通过这些符号,变量中的部分内容可以被删除、替换和替代。在 Shell 中,变量的删除、替换和替代也是非常重要的。通过简单操作修改变量,可以减少代码的行数并提…

水土保持设计乙级资质升甲级的条件?

水土保持设计乙级资质升为甲级资质的具体条件可能因地区政策及行业标准更新有所变动,但一般会涉及以下几个关键方面: 企业综合能力: 企业应具有良好的社会信誉,无不良记录。注册资本要求通常更高,甲级资质可能要求注册…