DeepSeek教unity------MessagePack-02

内置支持类型:

对象序列化

MessagePack for C# 可以序列化你自己定义的公共类或结构体类型。默认情况下,可序列化的类型必须用 [MessagePackObject] 属性进行注解,成员需要用 [Key] 属性进行注解。键可以是索引(整数)或任意字符串。如果所有键都是索引,则使用数组进行序列化,这在性能和二进制大小方面具有优势。否则,将使用 MessagePack 映射(字典)【MessagePack maps (dictionaries) will be used】。

1、如果你使用 [MessagePackObject(keyAsPropertyName: true)],则成员不需要显式的 Key 属性,但会使用字符串键。

2、所有公共实例成员(字段和属性)都将被序列化。如果要忽略某些公共成员,可以使用 [IgnoreMember] 属性对成员进行注解。

3、任何可序列化的结构或类都必须具有公共访问权限;私有和内部结构及类不能被序列化!

4、你应该使用索引键(整数)还是字符串键?我们建议使用索引键以实现更快的序列化和更紧凑的二进制表示,这比字符串键更有优势。然而,在调试时,字符串键中的额外信息可能会非常有用。

/****************************************************
    文件:Test_02.cs
	作者:Edision
    日期:#CreateTime#
	功能:示例2
*****************************************************/

using MessagePack;
using UnityEngine;

public class Test_02 : MonoBehaviour
{
    public void Test()
    {
        // [10,20]
        Debug.Log($"【Test_02Logo】{MessagePackSerializer.SerializeToJson(new Sample1 { Foo = 10, Bar = 20 })}");

        // {"foo":10,"bar":20}
        Debug.Log($"【Test_02Logo】{MessagePackSerializer.SerializeToJson(new Sample2 { Foo = 10, Bar = 20 })}");

        // {"Foo":10}
        Debug.Log($"【Test_02Logo】{MessagePackSerializer.SerializeToJson(new Sample3 { Foo = 10, Bar = 20 })}");
    }

    [MessagePackObject]
    public class Sample1
    {
        [Key(0)]
        public int Foo { get; set; }
        [Key(1)]
        public int Bar { get; set; }
    }

    [MessagePackObject]
    public class Sample2
    {
        [Key("foo")]
        public int Foo { get; set; }
        [Key("bar")]
        public int Bar { get; set; }
    }

    [MessagePackObject(keyAsPropertyName: true)]
    public class Sample3
    {
        // 不需要 Key 属性
        public int Foo { get; set; }

        // 如果要忽略一个公共成员,可以使用 IgnoreMember 属性
        [IgnoreMember]
        public int Bar { get; set; }
    }

}

5、当类发生变化或扩展时,要注意版本控制。如果序列化的二进制数据中不存在某个键,MessagePackSerializer 会将成员初始化为其默认值,这意味着使用引用类型的成员可能会被初始化为 null。如果你使用索引键(整数),键应从 0 开始并依次递增。如果后期版本停止使用某些成员,你应该保留这些过时的成员(C# 提供了 Obsolete 属性来注解这些成员),直到所有其他客户端有机会更新并移除对这些成员的使用。此外,当索引键的值“跳跃”很大,导致序列中出现空隙时,这将对二进制大小产生负面影响,因为会在结果数组中插入 null 占位符。然而,你不应该重用已删除成员的索引,以避免客户端之间的兼容性问题或在尝试反序列化旧数据块时出现问题。

6、如果你不想显式地用 MessagePackObject/Key 属性进行注解,而是希望像使用 Json.NET 那样使用 MessagePack for C#,你可以利用无合约解析器。

7、如果你想序列化私有成员,可以使用其中一个 *AllowPrivate 解析器。

/****************************************************
    文件:Test_03.cs
	作者:Edision
    日期:#CreateTime#
	功能:示例3:索引空隙和结果占位符的例子
*****************************************************/

using MessagePack;
using MessagePack.Resolvers;
using System;
using UnityEngine;

public class Test_03 : MonoBehaviour
{
    public void Test()
    {
        //************************************************************************//
        // [null,null,null,0,null,null,null,null,null,null,0]
        Debug.Log($"【Test_03Logo】" + MessagePackSerializer.SerializeToJson(new IntKeySample()));

        //************************************************************************//
        var data = new ContractlessSample { MyProperty1 = 99, MyProperty2 = 9999 };
        var bin = MessagePackSerializer.Serialize(data, MessagePack.Resolvers.ContractlessStandardResolver.Options);
        // {"MyProperty1":99,"MyProperty2":9999}
        Debug.Log($"【Test_03Logo】{MessagePackSerializer.ConvertToJson(bin)}");

        //************************************************************************//
        // 你也可以将 ContractlessStandardResolver 设置为默认解析器。
        // (全局状态;不推荐在编写库代码时使用)
        MessagePackSerializer.DefaultOptions = MessagePack.Resolvers.ContractlessStandardResolver.Options;
        var bin2 = MessagePackSerializer.Serialize(data);
        // {"MyProperty1":99,"MyProperty2":9999}
        Debug.Log($"【Test_03Logo】{MessagePackSerializer.ConvertToJson(bin2)}");

        //************************************************************************//

        var privateData = new PrivateSample();
        privateData.SetX(9999);
        //你可以选择 StandardResolverAllowPrivate 或 ContractlessStandardResolverAllowPrivate
        var privateBin = MessagePackSerializer.Serialize(privateData, ContractlessStandardResolverAllowPrivate.Options);
        Debug.Log($"【Test_03Logo】{MessagePackSerializer.ConvertToJson(privateBin)}");//【Test_03Logo】[9999]
        // 反序列化
        var deserializedData = MessagePackSerializer.Deserialize<PrivateSample>(privateBin, ContractlessStandardResolverAllowPrivate.Options);
        deserializedData.PrintPrivateField(); // 输出:Test_03Logo】PrivateField: 9999
    }

    [MessagePackObject]
    public class IntKeySample
    {
        [Key(3)]
        public int A { get; set; }
        [Key(10)]
        public int B { get; set; }
    }

    /// <summary>
    /// 无合约示例
    /// </summary>
    public class ContractlessSample
    {
        public int MyProperty1 { get; set; }
        public int MyProperty2 { get; set; }
    }
}

[MessagePackObject]
public partial class PrivateSample
{
    [Key(0)]
    int x;

    public void SetX(int v)
    {
        x = v;
    }

    public int GetX()
    {
        return x;
    }

    public void PrintPrivateField()
    {
        Debug.Log($"Test_03Logo】PrivateField: {x}");
    }
}

序列化回调

实现 IMessagePackSerializationCallbackReceiver 接口的对象将在序列化/反序列化期间收到 OnBeforeSerialize 和 OnAfterDeserialize 调用。

    
    public void Test()
    {
        var mc = new SampleCallback { Key = 0 };
        byte[] bytes =  MessagePackSerializer.Serialize(mc);
        SampleCallback sc = MessagePackSerializer.Deserialize<SampleCallback>(bytes);
    }

    [MessagePackObject]
    public class SampleCallback : IMessagePackSerializationCallbackReceiver
    {
        [Key(0)]
        public int Key { get; set; }

        public void OnBeforeSerialize()
        {
            Debug.Log("OnBefore");
        }

        public void OnAfterDeserialize()
        {
            Debug.Log("OnAfter");
        }
    }

总结

  • 索引间隙会导致 MessagePack 在序列化时插入占位符。

  • 反序列化时,占位符会被转换为对应类型的默认值。

  • 在设计数据结构时,尽量避免不必要的索引间隙,以减少序列化后的数据大小和处理开销。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/970187.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

部门管理(体验,最原始方法来做,Django+mysql)

本人初学&#xff0c;写完代码在此记录和复盘 在创建和注册完APP之后&#xff08;我的命名是employees&#xff09;&#xff0c;编写models.py文件创建表 手动插入了几条数据 1.部门查询 urls.py和views.py在编写之前&#xff0c;都要注意导入对应的库 urls.py&#xff1a;…

爬虫实战:利用代理ip爬取推特网站数据

引言 亮数据-网络IP代理及全网数据一站式服务商屡获殊荣的代理网络、强大的数据挖掘工具和现成可用的数据集。亮数据&#xff1a;网络数据平台领航者https://www.bright.cn/?promoRESIYEAR50/?utm_sourcebrand&utm_campaignbrnd-mkt_cn_csdn_yingjie202502 在跨境电商、社…

C#windows窗体人脸识别

一、创建一个数据库&#xff0c;名为TestFaceDB 里面有一张表就OK了&#xff0c;表名Users,表里面有几个字段我说明一下&#xff1a; id--------------------bigint----------------------编号 name--------------varchar(50)-----------------用户名 phone--------------v…

opencv中minAreaRect函数输出角度问题

opencv中minAreaRect函数输出角度问题 新版opencv中minAreaRect函数计算最小外接矩形时&#xff0c;角度范围由旧版的[-90, 0]变为[0, 90]。 cv2.minAreaRect输入&#xff1a;四边形的四个点&#xff08;不要求顺序&#xff09;。 输出&#xff1a;最小外接矩形的中心点坐标x…

Eclipse:关闭多余的工具条

Eclipse默认的工具条非常多&#xff0c;可以通过如下方法选择关闭一些不常用的&#xff1a; 1.选择菜单Window -> Perspective -> Customize Perspective 2.根据需要勾选Toolbar Visbility下面的工具条项

电商小程序(源码+文档+部署+讲解)

引言 随着移动互联网的快速发展&#xff0c;电商小程序成为连接消费者与商家的重要桥梁。电商小程序通过数字化手段&#xff0c;为消费者提供了一个便捷、高效的购物平台&#xff0c;从而提升购物体验和满意度。 系统概述 电商小程序采用前后端分离的架构设计&#xff0c;服…

MySQL单表存多大的数据量比较合适

前言 经常使用MySQL数据库的小伙伴都知道&#xff0c;当单表数据量达到一定的规模以后&#xff0c;查询性能就会显著降低。因此&#xff0c;当单表数据量过大时&#xff0c;我们往往要考虑进行分库分表。那么如何计算单表存储多大的数据量合适&#xff1f;当单表数据达到多大的…

Visual Studio Code支持WSL,直接修改linux/ubuntu中的文件

步骤1 开始通过 WSL 使用 VS Code | Microsoft Learn 点击远程开发扩展包。 步骤2 Remote Development - Visual Studio Marketplace 点击install&#xff0c; 允许打开Visual Studio Code。 步骤3 共有4项&#xff0c;一齐安装。 步骤4 在WSL Linux(Ubuntu)中&#xf…

微服务SpringCloud Alibaba组件nacos教程【详解naocs基础使用、服务中心配置、集群配置,附有案例+示例代码】

一.Nacos教程 文章目录 一.Nacos教程1.1 Nacos简介1.2 nacos基本使用直接下载打包服务源码方式启动 1.3 创建nacos客服端1.4 nacos集群配置1.5 nacos配置中心 1.1 Nacos简介 nacos是spring cloud alibaba生态中非常重要的一个组件&#xff0c;它有两个作用&#xff1a; 1:注册…

2024年终总结和2025年规划

2024年的主线是AI基础的学习和读书&#xff0c;虽然AI学习花费了更多的时间&#xff0c;但是读书长久看来于我是更重要的事情&#xff0c;哈哈哈&#xff0c;因此先简单回顾一下读书记忆&#xff0c;回顾我的2024&#xff0c;再展望一下我的2025. 我的2024年记忆 读万卷书&am…

实时云渲染:驱动XR技术产业化腾飞的核心引擎

在科技飞速发展的当下&#xff0c;扩展现实&#xff08;XR&#xff09;技术正以前所未有的速度融入人们的生活与工作&#xff0c;为用户打造出沉浸式逼真的虚拟环境。据知名XR媒体XR Today的最新数据显示&#xff0c;2024年全球XR市场规模已突破500亿美元&#xff0c;预计到202…

【AI编程】体验a0.dev:专为移动端app的对话式AI编程工具

摘要 体验专为移动端APP开发的AI编程工具 a0.dev&#xff0c;并附上实践过程和价格说明 体验a0.dev&#xff1a;专为移动端app的对话式AI编程工具 最近在探索新的AI编程工具时&#xff0c;发现了a0.dev&#xff0c;一个专注于移动端应用开发的对话式AI编程工具。今天就和大家分…

基于若依开发的工程项目管系统开源免费,用于工程项目投标、进度及成本管理的OA 办公开源系统,非常出色!

一、简介 今天给大家推荐一个基于 RuoYi-Flowable-Plus 框架二次开发的开源工程项目管理系统&#xff0c;专为工程项目的投标管理、项目进度控制、成本管理以及 OA 办公需求设计。 该项目结合了 Spring Boot、Mybatis、Vue 和 ElementUI 等技术栈&#xff0c;提供了丰富的功能…

数据库数据恢复—MongoDB丢失_mdb_catalog.wt文件导致报错的数据恢复案例

MongoDB数据库存储模式为文档数据存储库&#xff0c;存储方式是将文档存储在集合之中。 MongoDB数据库是开源数据库&#xff0c;同时提供具有附加功能的商业版本。 MongoDB中的数据是以键值对(key-value pairs)的形式显示的。在模式设计上&#xff0c;数据库受到的约束更少。这…

小米 R3G 路由器(Pandavan)实现网络打印机功能

小米 R3G 路由器&#xff08;Pandavan&#xff09;实现网络打印机功能 一、前言 家中有多台 PC 设备需要打印服务&#xff0c;但苦于家中的 Epson L380 打印机没有网络打印功能&#xff0c;并且配置 Windows 共享打印机实在是过于繁琐且需要共享机保持唤醒状态过于费电。想到…

笔记8——模式匹配 match语句(仅在Python 3.10及以上版本中可用)

文章目录 模式匹配 match语句(仅在 Python 3.10及以上版本 中可用)基本语法基本匹配操作应用场景 模式匹配 match语句(仅在 Python 3.10及以上版本 中可用) Python 3.10 及以上版本中才引入了 match 语句用于简化复杂的条件判断和数据解构&#xff1b;类似于其他语言中的 swit…

Edge浏览器清理主页

我们都知道&#xff0c;Microsoft Edge浏览器是微软创造的搜索浏览器&#xff0c;Windows10、11自带。但是你可以看到&#xff0c;每次你打开Edge浏览器的时候都可以看到许多的广告&#xff0c;如图&#xff1a; 导致打开Edge浏览器的时候会遭受卡顿&#xff0c;广告骚扰&#…

JVM类加载和垃圾回收(详细)

文章目录 JVM介绍JDK/JRE/JVM的关系 内存结构堆程序计数器虚拟机栈本地方法栈本地内存 类文件字节码文件结构 类加载类的生命周期加载类加载器双亲委派模型 链接初始化类卸载 垃圾回收堆空间的基本结构内存分配和回收原则死亡对象判断方法垃圾收集算法垃圾收集器 JVM 介绍 JD…

算法——结合实例了解深度优先搜索(DFS)

一&#xff0c;深度优先搜索&#xff08;DFS&#xff09;详解 DFS是什么&#xff1f; 深度优先搜索&#xff08;Depth-First Search&#xff0c;DFS&#xff09;是一种用于遍历或搜索树、图的算法。其核心思想是尽可能深地探索分支&#xff0c;直到无法继续时回溯到上一个节点…

[c语言日寄]在不完全递增序中查找特定要素

【作者主页】siy2333 【专栏介绍】⌈c语言日寄⌋&#xff1a;这是一个专注于C语言刷题的专栏&#xff0c;精选题目&#xff0c;搭配详细题解、拓展算法。从基础语法到复杂算法&#xff0c;题目涉及的知识点全面覆盖&#xff0c;助力你系统提升。无论你是初学者&#xff0c;还是…