切换导航
简历
工具
演示
查询
导航菜单
服务端
30
前端
114
数据库
82
进阶开发
8
桌面程序
2
QA
15
软件使用
36
规范协议
5
操作系统
11
AI
0
复用资源
6
硬件
0
标签
C# 基础
Mybatis
ADO.NET
ASP.NET
Python 基础
Linq
Web Forms
.NET
Spring
SpringBoot
SpringCloud
.NET Core 中间件
Maven
.NET 类库
ASP.NET MVC
EF
NHibernate
WebApi
Java
外部链接
.NET Core SDK和运行时安装包
淘宝 NPM 镜像
查询网
Tables Generator线上表格转换工具
引用cdn在线脚本和样式
首页
服务端
C# 装箱与取消装箱
[TOC] ## 1. 装箱与取消装箱 装箱是将值类型转换为 object 类型或由此值类型实现的任何接口类型的过程。 常见语言运行时 (CLR) 对值类型进行装箱时,会将值包装在 System.Object 实例中并将其存储在托管堆中。 取消装箱将从对象中提取值类型。 装箱是`隐式`的;取消装箱是`显式`的 ```csharp public static string Example() { int i = 10; object o = i; // 装箱 int j = (int)o // 拆箱 msg = $"i={i},j={j}"; return msg; } ``` ### 1.1. 装箱 装箱用于在垃圾回收堆中存储值类型。 装箱是值类型到 object 类型或到此值类型所实现的任何接口类型的隐式转换。 对值类型装箱会在堆中分配一个对象实例,并将该值复制到新的对象中。 上面示例中的 <mark> object o = i </mark> 就是一个装箱的过程,此语句的结果是在堆栈上创建对象引用 o,而在堆上则引用 int 类型的值。 该值是赋给变量 i 的值类型值的一个副本。 以下装箱转换图说明了 i 和 o 这两个变量之间的差异  **示例:** ```csharp public static string Example() { int i = 10; object o = i; i = 20; msg = $"i={i},o={o}"; return msg; // 输出i=20,o=20 } ``` 示例表明原始值类型和装箱的对象使用不同的内存位置,因此能够存储不同的值。 ### 1.2. 取消装箱 取消装箱是从 object 类型到值类型或从接口类型到实现该接口的值类型的显式转换。 取消装箱操作包括: + 检查对象实例,以确保它是给定值类型的装箱值。 + 将该值从实例复制到值类型变量中 在最开始的示例中 <mark> int j = (int)o </mark> 语句是一个取消装修的过程,以下拆箱转换图说明了 i 和 j 和 o 这两个变量之间的差异  要在运行时成功取消装箱值类型,被取消装箱的项必须是对一个对象的引用,该对象是先前通过装箱该值类型的实例创建的。 尝试取消装箱 null 会导致 NullReferenceException。 尝试取消装箱对不兼容值类型的引用会导致 InvalidCastException。 **示例:**InvalidCastException错误的一个示例 ```csharp class TestUnboxing { static void Main() { int i = 123; object o = i; try { int j = (short)o; // 将此语句改成 int j = (int)o 就能正常运行 System.Console.WriteLine("Unboxing OK."); } catch (System.InvalidCastException e) { System.Console.WriteLine("{0} Error: Incorrect unboxing.", e.Message); // 输出:Specified cast is not valid. Error: Incorrect unboxing. } } } ``` ### 1.3. 性能 相对于简单的赋值而言,装箱和取消装箱过程需要进行大量的计算。 对值类型进行装箱时,必须分配并构造一个新对象。 取消装箱所需的强制转换也需要进行大量的计算,只是程度较轻。 > Tips:如果值类型必须被频繁装箱,那么在这些情况下最好避免使用值类型(例如在诸如 `System.Collections.ArrayList` 的非泛型集合类中)。 可通过使用泛型集合(例如 `System.Collections.Generic.List<T>`)来避免装箱值类型。 装箱和取消装箱过程需要进行大量的计算。 对值类型进行装箱时,必须创建一个全新的对象。 这可能比简单的引用赋值用时最多长 20 倍。 取消装箱的过程所需时间可达赋值操作的4倍 [========] ## 参考资料 > [【装箱和取消装箱(C# 编程指南)】](https://learn.microsoft.com/zh-cn/dotnet/csharp/programming-guide/types/boxing-and-unboxing)
扫一扫手机看
点击排行
windows 文件资源管理器使用
Layui 弹窗open使用说明
SQL Server 中字符串函数使用
C# 使用QQ邮箱代理做邮件接收功能
SQL Server关于apply的两种形式cross apply 和 outer apply
ASP.NET MVC 模型的自定义验证
nvm安装及常用命令
SQL Server 中数据类型转换
SQL Server 中WITH AS短语的使用
IE浏览器下AJAX缓存问题导致数据不更新的解决办法
订阅号