.NET C# 装箱与拆箱
.NET C# 装箱与拆箱
目录
- .NET C# 装箱与拆箱
- 1 装箱 (Boxing)
- 1.1 过程:
- 1.2 示例:
- 2 拆箱 (Unboxing)
- 2.1 过程:
- 2.2 示例:
- 3 性能影响
- 4 性能优化
- 4.1 使用泛型集合
- 示例:
- 4.2 使用`Nullable<T>`
- 示例:
- 4.3 避免使用非泛型集合
- 示例:
- 4.4 避免在接口类型上操作值类型
- 4.5 使用结构体实现接口时,小心装箱
- 示例:
- 4.6 使用`readonly struct`优化性能
- 示例:
- 4.7 使用`Span<T>`和`Memory<T>`
- 示例:
- 4.8 使用内联方法(`[MethodImpl(MethodImplOptions.AggressiveInlining)]`)
- 示例:
在C#中,装箱和拆箱是将值类型转换为引用类型及其逆过程的操作。理解装箱和拆箱对于性能优化和正确使用类型转换非常重要。下面详细介绍这两个过程。
1 装箱 (Boxing)
装箱是将值类型转换为引用类型的过程。值类型存储在栈中,而引用类型存储在堆中。装箱过程会将值类型的值拷贝到堆中,并创建一个引用对象。
1.1 过程:
- 在堆中分配内存以存储值类型数据和类型信息。
- 将值类型数据拷贝到新分配的内存中。
- 返回对该内存的引用。
1.2 示例:
int value = 123; // 值类型
object obj = value; // 装箱,将值类型转换为引用类型
在这个示例中,value
是一个整数,属于值类型。当我们将它赋值给obj
时,发生了装箱操作,obj
现在是对堆中整数值123的引用。
2 拆箱 (Unboxing)
拆箱是将引用类型转换回值类型的过程。拆箱时必须确保引用类型实际上是被装箱的值类型,否则会抛出InvalidCastException
。
2.1 过程:
- 检查引用是否指向已装箱的值类型数据。
- 从堆中提取值类型数据并复制到栈上的值类型变量中。
2.2 示例:
object obj = 123; // 装箱
int value = (int)obj; // 拆箱
在这个示例中,obj
包含装箱的整数值123。当我们将obj
拆箱为整数时,需要进行显式类型转换,即(int)obj
。这会将引用类型转换回值类型,并将数据复制回栈中的value
。
3 性能影响
- 装箱和拆箱是开销较大的操作,因为它们涉及堆内存的分配和释放以及数据的复制。
- 尽量避免频繁的装箱和拆箱操作。例如,使用
List<int>
而不是ArrayList
来存储整数,这样可以避免装箱和拆箱操作,因为List<int>
是类型安全的。
4 性能优化
一些策略和技巧可以帮助减少或避免装箱和拆箱操作。以下是一些详细的方法:
4.1 使用泛型集合
泛型集合类如List<T>
、Dictionary<TKey, TValue>
、Queue<T>
、Stack<T>
等,都可以避免值类型的装箱和拆箱。泛型允许在编译时确定类型,从而直接在值类型上操作,而不需要转换为引用类型。
示例:
// 使用泛型集合避免装箱和拆箱
List<int> numbers = new List<int>();
numbers.Add(42); // 不会发生装箱
int number = numbers[0]; // 不会发生拆箱
4.2 使用Nullable<T>
Nullable<T>
结构(也可以使用T?
语法)允许值类型可以为空,而不需要装箱。
示例:
int? nullableInt = 5; // 不会发生装箱
nullableInt = null; // 不会发生装箱if (nullableInt.HasValue)
{int value = nullableInt.Value; // 不会发生拆箱
}
4.3 避免使用非泛型集合
尽量避免使用非泛型集合类如ArrayList
、Hashtable
、Queue
、Stack
等,因为它们会导致值类型的装箱和拆箱。可以使用对应的泛型版本。
示例:
// 避免使用ArrayList,因为它会导致装箱和拆箱
ArrayList arrayList = new ArrayList();
arrayList.Add(42); // 装箱
int value = (int)arrayList[0]; // 拆箱// 使用List<int>来避免装箱和拆箱
List<int> list = new List<int>();
list.Add(42); // 不会发生装箱
int value2 = list[0]; // 不会发生拆箱
4.4 避免在接口类型上操作值类型
当值类型通过接口进行操作时,会发生装箱。例如:
int x = 10;
IComparable comparable = x; // 装箱
int result = comparable.CompareTo(5); // 拆箱
避免这种情况的方法是直接在值类型上操作,而不是通过接口:
int x = 10;
int result = x.CompareTo(5); // 不会发生装箱和拆箱
4.5 使用结构体实现接口时,小心装箱
如果结构体实现了接口,并且接口方法在结构体实例上被调用时,会发生装箱。可以通过显示实现接口或者直接调用结构体的方法来避免装箱。
示例:
struct MyStruct : IComparable<MyStruct>
{public int CompareTo(MyStruct other){// 实现接口方法return 0;}
}MyStruct a = new MyStruct();
MyStruct b = new MyStruct();
int result = a.CompareTo(b); // 不会发生装箱IComparable<MyStruct> comparable = a;
result = comparable.CompareTo(b); // 装箱
4.6 使用readonly struct
优化性能
在一些场景下,使用readonly struct
可以提高性能,因为它们是不可变的,编译器可以进行更多优化,并且在某些情况下可以减少装箱。
示例:
readonly struct ImmutablePoint
{public int X { get; }public int Y { get; }public ImmutablePoint(int x, int y){X = x;Y = y;}
}
4.7 使用Span<T>
和Memory<T>
在需要处理大块内存时,使用Span<T>
和Memory<T>
可以避免装箱和拆箱,提供更高效的内存操作。
示例:
Span<int> span = stackalloc int[100]; // 不会发生装箱
for (int i = 0; i < span.Length; i++)
{span[i] = i; // 直接操作,不会发生装箱和拆箱
}
4.8 使用内联方法([MethodImpl(MethodImplOptions.AggressiveInlining)]
)
在性能关键的代码中,内联方法可以减少函数调用开销,并在某些情况下避免装箱和拆箱。
示例:
using System.Runtime.CompilerServices;struct MyStruct
{public int Value;[MethodImpl(MethodImplOptions.AggressiveInlining)]public void SetValue(int value){Value = value;}
}
通过综合使用这些方法,可以有效减少或避免装箱和拆箱操作,提高C#程序的性能。
相关文章:
.NET C# 装箱与拆箱
.NET C# 装箱与拆箱 目录 .NET C# 装箱与拆箱1 装箱 (Boxing)1.1 过程:1.2 示例: 2 拆箱 (Unboxing)2.1 过程:2.2 示例: 3 性能影响4 性能优化4.1 使用泛型集合示例: 4.2 使用Nullable<T>示例: 4.3 避…...
springboot与flowable(9):候选人组
act_id_xxx相关表存储了所有用户和组的数据。 一、维护用户信息 Autowiredprivate IdentityService identityService;/*** 维护用户*/Testvoid createUser() {User user identityService.newUser("zhangsan");user.setEmail("zhangsanqq.com");user.setF…...
为什么要选择华为 HCIE-Security 课程?
2020 年我国网络安全市场规模达到 680 亿元,同比增长 25%。随着对网络安全的愈加重视及布局,市场规模将持续扩大。 近年来,随着“云大物工移智”等新兴技术的快速发展和普及应用,数字化已经融入社会经济生活的方方面面,…...
C++之std::queue::emplace
std::queue::emplace 是 C STL 中 std::queue 容器的成员函数,它用于在队列的末尾就地构造一个新元素。这个函数类似于 std::queue::push,但是 emplace 允许你通过传递参数来构造元素,而不需要显式地创建一个元素对象。 理解 std::queue::em…...
Vue3 - 在项目中使用vue-i18n不生效的问题
检查和配置 Vue I18n 确保你已经正确安装了Vue I18n并且配置了组合API模式。 安装 Vue I18n npm install vue-i18nnext配置 i18n.js import { createI18n } from vue-i18n; import messages from ./messages;const i18n createI18n({legacy: false, // 使用组合 API 模式l…...
Day 44 Ansible自动化运维
Ansible自动化运维 几种常用运维工具比较 Puppet —基于 Ruby 开发,采用 C/S 架构,扩展性强,基于 SSL,远程命令执行相对较弱ruby SaltStack —基于 Python 开发,采用 C/S 架构,相对 puppet 更轻量级,配置语法使用 YAML,使得配置脚本更简单 Ansible —基于 …...
Excel/WPS《超级处理器》功能介绍与安装下载
超级处理器是基于Excel或WPS开发的一款插件,拥有近300个功能,非常简单高效的处理表格数据,安装即可使用。 点击此处:超i处理器安装下载 Excel菜单,显示如下图所示: WPS菜单显示,如下图所示&am…...
U-Net for Image Segmentation
1.Unet for Image Segmentation 笔记来源:使用Pytorch搭建U-Net网络并基于DRIVE数据集训练(语义分割) 1.1 DoubleConv (Conv2dBatchNorm2dReLU) import torch import torch.nn as nn import torch.nn.functional as F# nn.Sequential 按照类定义的顺序去执行模型&…...
POI导入带有合并单元格的excel,demo实例,直接可以运行
直接可以运行 import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.s…...
【C语言】解决C语言报错:Use-After-Free
文章目录 简介什么是Use-After-FreeUse-After-Free的常见原因如何检测和调试Use-After-Free解决Use-After-Free的最佳实践详细实例解析示例1:释放内存后未将指针置为NULL示例2:多次释放同一指针示例3:全局或静态指针被释放后继续使用示例4&am…...
C语言经典例题-19
1.字符串左旋结果 题目内容:写一个函数,判断一个字符串是否为另外一个字符串旋转之后的字符串。 例:给定s1 AABCD和s2 BCDAA,返回1 给定s1 abcd和s2 ACBD,返回0 AABCD左旋一个字符得到ABCDA AABCD左旋两个字符得到BCDAA AABCD右旋一…...
AlmaLinux 更换CN镜像地址
官方镜像列表 官方列表:https://mirrors.almalinux.org/CN 开头的站点,不同区域查询即可 一键更改镜像地址脚本 以下是更改从默认更改到阿里云地址 cat <<EOF>>/AlmaLinux_Update_repo.sh #!/bin/bash # -*- coding: utf-8 -*- # Author:…...
【笔记】【矩阵的二分】668. 乘法表中第k小的数
力扣链接:题目 参考地址:参考 思路:二分查找 把矩阵想象成一维的已排好序的数组,用二分法找第k小的数字。 假设m行n列,则对应一维下标范围是从1到mn,初始: l1; rmn; mid(lr)/2 设mid在第i行&a…...
红米手机RedNot11无法使用谷歌框架,打开游戏闪退的问题,红米手机如何开启谷歌框架
红米手机RedNot11无法使用谷歌框架,打开游戏闪退的问题, 1.问题描述2.问题原因3.解决方案3.1配置谷歌框架:3.1软件优化 4.附图 1.问题描述 红米手机打开安卓APP没有广告,直接闪退,无法使用谷歌框架 异常关键词中包含&…...
emqx5.6.1 数据、配置备份与迁移
EMQX 支持导入和导出的数据包括: EMQX 配置重写的内容: 认证与授权配置规则、连接器与 Sink/Source监听器、网关配置其他 EMQX 配置内置数据库 (Mnesia) 的数据 Dashboard 用户和 REST API 密钥客户端认证凭证(内置数据库密码认证、增强认证…...
VUE3脚手架工具cli配置搭建及创建VUE工程
1、VUE的脚手架工具(CLI) 开发大型vue的时候,不能通过html编写一个大型的项目,这个时候需要用到vue的脚手架工具 通过vue的脚手架,可以快速的生成vue工程 1.1、安装nodejs和npm 【下载nodejs】 https://nodejs.org/en 【安装…...
前端开发之DNS协议
上一篇👉: 前端开发之计算机网络模型认识 文章目录 DNS协议详介绍1. DNS 协议概述2. DNS协议与TCP/UDP3. DNS查询过程4. 迭代与递归查询5. DNS记录与报文结构资源记录类型对比 6. 总结 DNS协议详介绍 1. DNS 协议概述 DNS(Domain Name System…...
如何在 Tailwind CSS 中实现居中对齐
如何在 Tailwind CSS 中实现居中对齐: 1. 使用 text-center 类(针对行内元素或行内块元素) 这个类用于将文本或行内块元素水平居中对齐。 <div class"text-center"><span>这是一个行内元素</span> </div&g…...
【iOS】编译二进制文件说明
编译二进制文件说明 如何生成文件路径文件说明第一部分:.o文件第二部分:link第三部分:Segment第四部分:Symbol 如何生成 使用Xcode进行编译 ,会生成二进制相关文件,可以更详细看产物的布局 项目Target -&…...
红队内网攻防渗透:内网渗透之内网对抗:隧道技术篇防火墙组策略FRPNPSChiselSocks代理端口映射C2上线
红队内网攻防渗透 1. 内网隧道技术1.1 Frp内网穿透C2上线1.1.1 双网内网穿透C2上线1.1.1.1 服务端配置1.1.1.2 客户端配置1.1.2 内网穿透信息收集1.1.2.1、建立Socks节点(入站没限制采用)1.1.2.2 主动转发数据(出站没限制采用)1.2 Nps内网穿透工具1.2.1 NPS内网穿透C2上线1…...
qt+halcon实战
注意建QT工程项目用的是MSVC,如果选成MinGW,则会报错 INCLUDEPATH $$PWD/include INCLUDEPATH $$PWD/include/halconcppLIBS $$PWD/lib/x64-win64/halconcpp.lib LIBS $$PWD/lib/x64-win64/halcon.lib#include "halconcpp/HalconCpp.h" #include &quo…...
Java_POJO
概念 POJO即简单的Java对象,区别于JavaBean JavaBean:特殊的Java类,容易被重用或插入到其他应用程序中去,通过封装属性和方法成为具有某种功能或者处理某个业务的对象 这个类必须有public的无参构造器所有属性都是private的所有属…...
24年安克创新社招入职自适应能力cata测评真题分享北森测评高频题库
第一部分:安克创新自适应能力cata测评 感谢您关注安克创新社会招聘,期待与您一起弘扬中国智造之美。 为对您做出全面的评估,现诚邀您参加我们的在线测评。 测评名称:社招-安克创新自适应能力cata测评 第二部分:安克…...
OpenCV中的圆形标靶检测——findCirclesGrid()(三)
前面说到cv::findCirclesGrid2()内部先使用SimpleBlobDetector进行圆斑检测,然后使用CirclesGridClusterFinder算法类执行基于层次聚类的标靶检测。如下图所示,由于噪声的影响,SimpleBlobDetector检出的标靶可能包含噪声。 而CirclesGridClusterFinder算法类会执行基…...
C++拷贝构造函数、运算符重载函数、赋值运算符重载函数、前置++和后置++重载等的介绍
文章目录 前言一、拷贝构造函数1. 概念2. 特征3. 编译器生成默认拷贝构造函数4. 拷贝构造函数典型使用场景 二、运算符重载函数三、赋值运算符重载函数1. 赋值运算符重载格式2. 赋值运算符只能重载成类的成员函数不能重载成全局函数3.编译器生成一个默认赋值运算符重载4. 运算符…...
视频智能分析平台智能边缘分析一体机视频监控业务平台区域人数不足检测算法
智能边缘分析一体机区域人数不足检测算法是一种集成了先进图像处理、目标检测、跟踪和计数等功能的算法,专门用于实时监测和统计指定区域内的人数,并在人数不足时发出警报。以下是对该算法的详细介绍: 一、算法概述 智能边缘分析一体机区域…...
揭秘MMAdapt:如何利用AI跨领域战胜新兴健康谣言?
MMAdapt: A Knowledge-Guided Multi-Source Multi-Class Domain Adaptive Framework for Early Health Misinformation Detection 论文地址: MMAdapt: A Knowledge-guided Multi-source Multi-class Domain Adaptive Framework for Early Health Misinformation Detection …...
【云手机】数据安全如何保障?
安全办公,信息安全,这是企业使用云手机的初衷和目的,云手机在数据保密,远程办公等功能上有巨大的优势,也为企业提供了支持 首先就是云手机能够实现数据的集中管理和加密存储。所有办公相关的数据都存储在云端的安全服务…...
【算法专题--链表】删除排序链表中的重复元素 -- 高频面试题(图文详解,小白一看就懂!!)
目录 一、前言 二、题目描述 三、解题方法 ⭐双指针 四、总结与提炼 五、共勉 一、前言 删除排序链表中的重复元素这道题,可以说是--链表专题--,最经典的一道题,也是在面试中频率最高的一道题目,通常在面试中࿰…...
【ajax基础01】ajax简介
目录 一:ajax简介 1 什么是ajax 二:ajax使用 1 如何使用ajax 2 axios使用(重点) 三:案例 四:如何赚钱 一:ajax简介 1 什么是ajax AJAX(Asynchronous JavaScript And XML &am…...
笔记本网站开发背景/优化大师怎么提交作业
给你一个整数数组 nums 和一个整数 k。 如果某个 连续 子数组中恰好有 k 个奇数数字,我们就认为这个子数组是「优美子数组」。 请返回这个数组中「优美子数组」的数目。 示例 1: 示例 1: 输入:nums [1,1,2,1,1], k 3 输出&a…...
网站策划 要求/长沙百度开户
堆是堆(heap),栈是栈(stack),堆栈是栈。栈中分配的是基本类型和自定义对象的引用。堆中分配的是对象,也就是new出来的东西。 被所有线程共享。方法区/静态区 存放的是类信息和static变量、常量。 被所有线程共享。也可以…...
tiktok跨境电商运营/福建seo优化
int atoi(const char *_Str) double atof(const char *_String) 将字符串_Str转换成整型/浮点型数并返回。 int isdigit(int _C) 如果_C是数字,则为true。 getline 这个函数接受两个参数:一个输入流对象和一个string对象。 函数从输入流的下一行读…...
java可以做网站前台吗/百度网盘资源共享
目的 本文档介绍了如何设置和配置单节点Hadoop安装,以便您可以使用Hadoop MapReduce和Hadoop分布式文件系统(HDFS)快速执行简单的操作。 先决条件 支持平台 支持GNU / Linux作为开发和生产平台。 Hadoop在具有2000个节点的GNU / Linux集群…...
dreamweaver网站制作教程/产品推广软文
创建一个组。在组中放置一个矩形(整个圆的大小)(例如,矩形的高度和宽度设置为圆的直径),然后将圆弧添加到组中,并将圆弧布局位置设置为圆的半径。将组放在StackPane中,以便固定大小的组将在可调整大小的区域中居中。将StackPane放…...
ubuntu做网站服务器/网站推广优化外链
前言这几天拿到macbook就迫不及待的尝试了一下,刚开始前几天着实非常的不习惯。但是经过这几天的学习,感觉基本上掌握了其用法,马上就感觉这是一个生产代码、制作视频的利器。问过很多macbook的使用者都觉得用了很久不好用,安装的…...