Unity 委托与事件、装箱和拆箱

文章目录

  • 前言
  • 一、委托与事件
    • 1、委托的概念
    • 2、委托是什么
    • 3、事件是什么
  • 二、装箱和拆箱
    • 1、什么是装箱和拆箱
    • 2、堆、栈
    • 3、应用
    • 4、优化
  • 总结


前言


一、委托与事件

1、委托的概念

不知道大家在学习C#之前有没有学习过C/C++,在中后期会接触到指针。她不仅能指向变量的地址,还能指向函数的地址。本质上,指向的都是内存的地址。
而在C#中,万物皆是类,指针被封装到内部函数中,因此并不常见。所有函数指针的功能都以委托的方式完成。委托可以被视为更高级的函数指针,它不仅能将地址指向另一个函数,而且还能传递参数、获取返回值等多种信息。

委托具有以下属性:
委托类似于 C++ 函数指针,但委托完全面向对象,不像 C++ 指针会记住函数,委托会同时封装对象实例和方法。
委托允许将方法作为参数进行传递。
委托可用于定义回调方法。
委托可以链接在一起;例如,可以对一个事件调用多个方法。
方法不必与委托类型完全匹配。 有关详细信息,请参阅使用委托中的变体。
使用 Lambda 表达式可以更简练地编写内联代码块。 Lambda 表达式(在某些上下文中)可编译为委托类型。 若要详细了解 lambda 表达式,请参阅 lambda 表达式。
官方解释

2、委托是什么

委托并不是一个语言类型,而是一个实例。大多数语言实现delegate关键字 (keyword) ,这些语言的编译器能够派生自 MulticastDelegate 类。MulticastDelegate 类显式Delegate派生。 类 Delegate 不被视为委托类型;它是用于派生委托类型的类。
什么意思呢,我们不能自己写一个类继承MulticastDelegate类,只有编辑器或其他工具可以。
Delegate类中有一个变量是用来存储函数地址的,当变量操作=(等号)时,把函数地址赋值给变量保存起来。不过这个存储函数地址的变量是一个可变数组,你可以认为它是一个链表,每次直接赋值时会换一个链表。 Delegate委托类还重写了+=、-=这两个操作符,其实就是对应MulticastDelegate类的Combine()和Remove()方法,当对函数进行+=和-=操作时,相当于把函数地址推入链表尾部,或者移出链表。
下面是官方的解释,意思是C#编辑器设计了一个列表来执行delegate,虽然我们在代码中使用了 delegate 关键字来定义委托类型,但实际上编译器在编译时会将其重写成 Delegate 类。换句话说,delegate 关键字只是一种修饰用词,用来告诉编译器我们正在定义一个委托类型,但最终在编译后的代码中,委托类型会被转换成一个类,这个类是 System.MulticastDelegate 类的子类。

MulticastDelegate类中有一个已经连接好的delegate列表,被称为调用列表,它由一个或者更多个元素组成。当一个multicast delegate被启动调用时,所有在调用列表里的delegate都会按照它们出现的顺序被调用。如果在执行列表期间遇到一个错误,就会立即抛出异常并停止调用。

3、事件是什么

事件是对委托的再次封装,目的是限制用户直接操作委托实例中的变量。因此,事件不能通过等号(=)赋值,而是只能通过注册和注销方法来增减委托的数量。这种限制的好处是显而易见的:在多人合作开发时,公开的委托很容易被其他人无意覆盖,而事件能更好地维护项目的稳定性和可靠性。

二、装箱和拆箱

1、什么是装箱和拆箱

装箱和拆箱,装箱是指将值类型转换成引用类型,拆箱是指将引用类型转换为值类型。
装箱:

int a = 5;

object obj = a;

拆箱:

a = (int)obj;

装箱过程中,a赋值给obj,obj创建一个指针并指向a的数据空间。
拆箱过程中,obj复制一份数据给a。
值类型声明时即初始化自身,不能为null。而引用类分配内存后,不指向任何空间,默认为null。

2、堆、栈

栈是一种特殊的容器,用来存放对象,遵循先进后出的原则。它的存储空间是连续的,因此对栈数据的定位速度比较快。与之相反,堆是随机分配的空间,处理的数据比较多,定位速度较慢。堆内存的创建和删除节点的时间复杂度是O(lgn),而栈的时间复杂度则是O(1),因此栈的速度更快。
尽管栈速度快,但它的生命周期必须确定,销毁时必须按照特定次序进行,即从最后分配的部分开始销毁。因此,栈主要用于生命周期比较确定的场景,如函数调用和递归调用。相反,堆内存可以存放生命周期不确定的内存块,满足需要在需要删除时再删除的需求。因此,堆内存更适合用于存放全局类型的内存块,分配和销毁更加灵活。
但要注意,值类型和引用类型并不是对应栈内存和堆内存。栈内存主要为确定性生命周期的内存服务,堆内存则更多的是无序的随时可以释放的内存。值类型和引用类型能在堆也能在栈内,其中引用类型指针部分可以指向栈内或堆内。

3、应用

在项目中需要一个通用的接口时就需要装箱操作。

4、优化

装箱、拆箱时会不断分配和销毁内存,增减内存碎片。
我们需要尽量少用。怎么做呢。
1、使用泛型。
2、统一接口提前装箱、拆箱。
3、使用Struct时通过重载函数来避免装箱、拆箱。对于值类型(Struct)而言,如果没有重载 ToString() 和 GetType() 等方法,当调用它们时会发生装箱操作。装箱操作会将值类型转换为引用类型(Object 类型),这会导致内存块重新分配,从而带来性能损耗。
书中举例:
如果Struct A和Struct B都继承了接口I,我们调用的方法是void Test(I i)。当调用Test方法时,传进去的Struct A或Struct B的实例相当于提前执行了装箱操作,Test方法里拿到参数后就不用再担心内部再次出现装箱、拆箱的问题了。


总结

在项目中,需要注意委托、装箱与拆箱的使用,尽量避免性能损耗。使用泛型、重载函数、提前装箱等方式进行优化。期待你的精益求精,加油!

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

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

相关文章

【数据结构】-- 链表专题

链表的分类 前面我们实现了单链表,单链表只是链表的一种。可以根据以下几个标准来判断链表的类型: 1.单向或者双向 如图所示,单向链表中一个节点的指针域只储存了下一个节点的指针,能通过前一个节点访问后一个节点,无…

Vue 3.3 编译宏 vue3.3新增了一些语法糖和宏,包括泛型组件、defineSlots、defineEmits、defineOptions

Vue 3.3新增了一些语法糖和宏&#xff0c;包括泛型组件、defineSlots、defineEmits、defineOptions defineProps 父组件传参 <template><Child name"my"></Child> </template> <script setup lang"ts"> import Child fro…

使用Docker安装Yapi接口管理工具

简介&#xff1a; YAPI 是由去哪儿网移动架构组开发的一款可视化接口管理工具。它具有可视化管理、高效易用、功能强大等特点。它提供了便捷的接口创建、发布和维护方式&#xff0c;开发人员可以通过简单的操作实现接口管理。 YAPI 还支持类似 postman 的接口调试&#xff0c;对…

06-数组

1. 为什么需要数组 一个养鸡场有6只鸡&#xff0c;它们的体重分别是3kg&#xff0c;4kg&#xff0c;1kg&#xff0c;2kg&#xff0c;6kg&#xff0c;3kg。 没有数组&#xff0c;就需要定义六个变量&#xff0c;一个变量代表一只鸡的体重。 使用数组&#xff0c;就可以定义一…

TypeScript学习日志-第二十三天(装饰器Decorator)

装饰器Decorator 一、类装饰器 ClassDecorator 其中返回的 target 是 Http 的构造函数&#xff0c;有了构造函数就不会去破坏其自身原有的结构&#xff0c;当我们 Http 里面有多个属性或者方法的&#xff0c;当是我们不想看或者改变它&#xff0c;这时候可以在构造函数中增加即…

【Mybatis操作数据库】入门(一)

个人主页&#xff1a;兜里有颗棉花糖 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 兜里有颗棉花糖 原创 收录于专栏【MyBatis框架】 本专栏旨在分享MyBatis框架的学习笔记&#xff0c;如有错误定当洗耳恭听&#xff0c;欢迎大家在评论区交流讨论&#x1f…

59岁前TVB男拳王内地登台疑黑面 被批耍大牌

现年59岁的郭政鸿在2015年离巢TVB后转往内地发展&#xff0c;密密拍剧、登台及直播带货&#xff0c;短短几年就已经储够钱&#xff0c;斥资过千万买楼&#xff0c;成功上车做业主&#xff0c;可见收入丰厚。 早前郭政鸿现身顺德&#xff0c;在酒吧登台唱歌&#xff0c;有网民上…

《铁路出行更便捷:火车票预定审批系统的设计与应用》

在现代化的铁路交通管理中&#xff0c;火车票预定审批系统扮演着至关重要的角色。它不仅能够有效管理员工出差、培训等需要乘坐火车的行程&#xff0c;还能够提高审批效率&#xff0c;减少人力成本&#xff0c;确保出行安全。本文将探讨火车票预定审批系统的设计原则和应用场景…

计算机毕业设计Python+Spark知识图谱医生推荐系统 医生门诊预测系统 医生数据分析 医生可视化 医疗数据分析 医生爬虫 大数据毕业设计 机器学习

摘 要 随着我国社会经济发展水平的不断提高&#xff0c;人们的物质生活水平也有了很大的改善&#xff0c;越来越多的人不满足于当前的医疗服务质量&#xff0c;由于地域和空间的限制&#xff0c;医疗资源不平衡&#xff0c;无法实现全民共享。针对当今社会中存在的求医难的问题…

智能家居2 -- 实现网络控制模块

这一模块的思路和前面的语言控制模块很相似&#xff0c;差别只是调用TCP 去控制 废话少说&#xff0c;放码过来 增添/修改代码 socket_interface.c #include <pthread.h>#include "socket_interface.h" #include "control.h" #include "socke…

【教程】超简单!如何将“在VSCode中打开”添加到右键菜单中

按照以下步骤进行操作&#xff1a; 打开注册表编辑器&#xff1a; 按下 Win R 组合键打开运行对话框。输入 regedit 并按下 Enter 键打开注册表编辑器。 导航到适当的注册表项&#xff1a; 转到以下注册表项&#xff1a;HKEY_CLASSES_ROOT\Directory\Background\shell 创建…

26版SPSS操作教程(高级教程第十九章)

目录 前言 粉丝及官方意见说明 第十九章一些学习笔记 第十九章一些操作方法 树模型、随机森林与最近邻元素法 树模型 数据准备 具体操作 结果解释 对案例的进一步分析 结果解释 考虑应用模型时的成本与收益 保存新数据 在选项中看错误分类成本和利润 结果解释…

【管理篇】如何管理情绪?

目录标题 为什么要特别关注激动和愤怒两种情绪呢&#xff1f;管理自己的情绪大致的步骤三层脑结构爬行脑情绪脑视觉脑 大家说的情绪管理&#xff0c;基本上都是对于情绪激动、生气甚至是愤怒的管理&#xff1b;日常所说的情绪化&#xff0c;一般也是指某个人特别容易情绪激动&a…

Gitlab自动化测试的配置

1. 代码分支命名规范检测 Setting → Repository → Push rules → Branch name&#xff0c;添加分支命名规范对应的正则表达式。如&#xff1a; ^(Release|Tag|Develop|Feature)_._.|Main$ 表示分支名只能以以下关键字之一开头&#xff1a;Release、Tag、Develop和Feature。 …

基于模糊控制的AMT自动变速汽车换档智能控制系统simulink建模与仿真

目录 1.课题概述 2.系统仿真结果 3.核心程序与模型 4.系统原理简介 5.完整工程文件 1.课题概述 基于模糊控制的AMT自动变速汽车换档智能控制系统simulink建模与仿真。 2.系统仿真结果 输入的V&#xff0c;Ac&#xff0c;a 输出的档位&#xff1a; 3.核心程序与模型 版…

【BST】Behavior Sequence Transformer for E-commerceRecommendation in Alibaba

一、提出背景 传统的Embedding&MLP模型结构将原始特征嵌入到低维向量中&#xff0c;然后将其concat后输入MLP进行最终推荐。DIN提出使用注意力机制来捕获候选项与用户先前点击的项之间的相似性。 然而&#xff0c;大多数这些工作只是连接不同的特征&#xff0c;而没有捕获用…

通过 Java 操作 redis -- hash 哈希表基本命令

目录 使用命令 hset&#xff0c;hget 使用命令 hexists 使用命令 hdel 使用命令 hkeys&#xff0c;hvals 使用命令 hmget&#xff0c;hmset 关于 redis hash 哈希表类型的相关命令推荐看Redis - hash 哈希表 要想通过 Java 操作 redis&#xff0c;首先要连接上 redis 服务…

AVL Cruise与Simulink联合仿真(通过MATLAB DLL方式)

最近毕业设计需要用到AVL Cruise与Simulink进行联合仿真&#xff0c;分析汽车模型的经济性。下面介绍一下我所知的AVL Cruise与Simulink联合仿真的几种方式&#xff0c;它们各自的优缺点&#xff0c;以及DLL方式联合仿真的具体配置过程。我这里用的MATLAB软件版本是2021a&#…

运行Spring Boot项目失败?显示java: 无法访问org.springframework.boot.SpringApplication,让我来看看~

idea项目运行报错截图&#xff1a; &#xff08;1&#xff09;查看错误提示“类文件具有错误的版本 61.0, 应为 52.0”&#xff0c;61.0对应的是jdk17&#xff0c;52.0对应1.8。 通过这个网址可以查询版本&#xff1a; https://stackoverflow.com/questions/9170832/list-of-ja…

Linux文本三剑客

文章目录 一、文本搜索工具--grep1、简介2、工作原理3、语法格式4、选项介绍5、实例测试5.1、-i选项5.2、-v选项5.3、-n选项5.4、-c选项5.5、-o选项5.6、-B选项5.7、-A选项5.8、-C选项5.9、-w选项5.10、-E选项5.11、-e选项 二、流编辑器--sed1、简介2、工作原理3、语法格式4、选…