装箱和拆箱是值类型和引用类型之间相互转换是要执行的操作。 

1. 装箱在值类型向引用类型转换时发生

2. 拆箱在引用类型向值类型转换时发生

光上述两句话不难理解,但是往深处了解,就需要一些篇幅来解释了。

我们先看装箱时都会发生什么事情,下面是一行最简单的装箱代码

object obj = 1;

这行语句将整型常量1赋给object类型的变量obj; 众所周知常量1是值类型,值类型是要放在栈上的,而object是引用类型,它需要放在堆上;要把值类型放在堆上就需要执行一次装箱操作。

这行语句的IL代码如下,请注意注释部分说明:

.locals init (
[0] object objValue
) //以上三行IL表示声明object类型的名称为objValue的局部变量
IL_0000: nop
IL_0001: ldc.i4.s 9 //表示将整型数9放到栈顶
IL_0003: box [mscorlib]System.Int32 //执行IL box指令,在内存堆中申请System.Int32类型需要的堆空间
IL_0008: stloc.0 //弹出堆栈上的变量,将它存储到索引为0的局部变量中

以上就是装箱所要执行的操作了,执行装箱操作时不可避免的要在堆上申请内存空间,并将堆栈上的值类型数据复制到申请的堆内存空间上,这肯定是要消耗内存和cpu资源的。我们再看下拆箱操作是怎么回事:

请看下面的C#代码:

object objValue = 4;
int value = (int)objValue;

上面的两行代码会执行一次装箱操作将整形数字常量4装箱成引用类型object变量objValue;然后又执行一次拆箱操作,将存储到堆上的引用变量objValue存储到局部整形值类型变量value中。

同样我们需要看下IL代码:

.locals init (
[0] object objValue,
[1] int32 'value'
) //上面IL声明两个局部变量object类型的objValue和int32类型的value变量
IL_0000: nop
IL_0001: ldc.i4.4 //将整型数字4压入栈
IL_0002: box [mscorlib]System.Int32 //执行IL box指令,在内存堆中申请System.Int32类型需要的堆空间
IL_0007: stloc.0 //弹出堆栈上的变量,将它存储到索引为0的局部变量中
IL_0008: ldloc.0//将索引为0的局部变量(即objValue变量)压入栈
IL_0009: unbox.any [mscorlib]System.Int32 //执行IL 拆箱指令unbox.any 将引用类型object转换成System.Int32类型
IL_000e: stloc.1 //将栈上的数据存储到索引为1的局部变量即value

拆箱操作的执行过程和装箱操作过程正好相反,是将存储在堆上的引用类型值转换为值类型并给值类型变量。

装箱操作和拆箱操作是要额外耗费cpu和内存资源的,所以在c# 2.0之后引入了泛型来减少装箱操作和拆箱操作消耗。

【.Net】深入理解C#的装箱和拆箱的更多相关文章

  1. 深入理解C#的装箱和拆箱(转)

    装箱和拆箱是值类型和引用类型之间相互转换是要执行的操作.  1. 装箱在值类型向引用类型转换时发生 2. 拆箱在引用类型向值类型转换时发生 光上述两句话不难理解,但是往深处了解,就需要一些篇幅来解释了 ...

  2. 全面理解java自动装箱和拆箱(转)

    自动装箱和拆箱从Java 1.5开始引入,目的是将原始类型值转自动地转换成对应的对象.自动装箱与拆箱的机制可以让我们在Java的变量赋值或者是方法调用等情况下使用原始类型或者对象类型更加简单直接. 如 ...

  3. 深入理解C#的装箱和拆箱

    个人理解(本质): 封箱是把值类型转换为引用类型 拆箱是把引用类型转换为值类型 封箱是把值类型转换为System.Object类型,或者转换为由值类型实现的接口类型: 例如: struct Mystr ...

  4. 深入理解Java之装箱与拆箱

    一.Java数据类型 1.在说装箱与拆箱之前,先说一下Java的基本数据类型,Java从数据类型上可以划分为值类型与引用类型,值类型是四类八种,分别是: 整数型:byte̵,short̵,int̵,l ...

  5. 【深入理解CLR】2:细谈值类型的装箱和拆箱

    装箱 总所周知,值类型是比引用类型更“轻型”的一种类型,因为它们不作为对象在托管堆中分配,不会被垃圾回收,也不通过指针来引用.但在许多情况下,都需要获取对值类型的一个实例的引用.例如,假定要创建一个A ...

  6. Java基础 带你深刻理解自动装箱,拆箱含义

    1.什么是装箱,什么是拆箱装箱:把基本数据类型转换为包装类.拆箱:把包装类转换为基本数据类型.基本数据类型所对应的包装类:int(几个字节4)- Integerbyte(1)- Byteshort(2 ...

  7. 如何理解Java中的自动拆箱和自动装箱?

    小伟刚毕业时面的第一家公司就被面试官给问住了... 如何理解Java中的自动拆箱和自动装箱? 自动拆箱?自动装箱?什么鬼,听都没听过啊,这...这..知识盲区... 回到家后小伟赶紧查资料,我透,这不 ...

  8. 关于C#理解装箱与拆箱

    目录 1.理解装箱 2.理解拆箱 3.生成的 IL 代码 4.实际应用 5.小结 1.理解装箱 简单地说,装箱就是将一个值类型的数据存储在一个引用类型的变量中. 假设你一个方法中创建了一个 int 类 ...

  9. 深入理解Java中的装箱与拆箱

    一.Java数据类型 1.在说装箱与拆箱之前,先说一下Java的基本数据类型,Java从数据类型上可以划分为值类型与引用类型,值类型是四类八种,分别是: 整数型:byte̵,short̵,int̵,l ...

随机推荐

  1. 剖析:如何用 SwiftUI 5天组装一个微信 —— 通讯录发现我篇

    前置资源 GitHub: SwiftUI-WeChatDemo 第零章:用 SwiftUI 5天组装一个微信 第一章:剖析:如何用 SwiftUI 5天组装一个微信 -- 聊天界面篇 通讯录 通讯录的 ...

  2. springboot-8-企业开发

    一.邮件发送 流程: mbqplwpheeyvgdjh 首先需要开启POS3/SMTP服务,这是一个邮件传输协议 点击开启 导入依赖 <!--mail--> <dependency& ...

  3. java对接c++发布的webservice接口,其中参数类型有base64Binary格式(无需将图片数据转化为c++中的结构体)

    接口名称: std::string SendVehiclePass(std::string VehiclePassInfo, struct xsd__base64Binary PlatePicData ...

  4. python批量修改图片名称

    import os class BatchRename(): def rename(self): # windows环境 """ os.rename() 方法用于命名文件 ...

  5. Python - 基础数据类型 tuple 元组

    元组简单介绍 元组是一个和列表和相似的数据类型,也是一个有序序列 两者拥有着基本相同的特性,但是也有很多不同的地方 声明元组 var = (1, 2, 3) var = ("1", ...

  6. SpringBoot下Schdule的配置与使用

    我们在平常项目开发中,经常会用到周期性定时任务,这个时候使用定时任务就能很方便的实现.在SpringBoot中用得最多的就是Schedule. 一.SpringBoot集成Schedule 1.依赖配 ...

  7. Adobe ColdFusion 文件读取漏洞(CVE-2010-2861)

    影响范围 Adobe ColdFusion 8.9版本中存在一处目录穿越漏洞 poc http://192.168.49.2:8500/CFIDE/administrator/enter.cfm?lo ...

  8. 计算机网络part2——物理层

    物理层概述 1.物理层基本概念 物理层解决如何在连接各种计算机的传输媒体上传输数据比特流,而不是指具体的传输媒体. 主要任务:确定与传输媒体接口有关的一些特性 特性: 机械特性 电气特性 功能特性 规 ...

  9. MySQL 事务、日志、锁、索引学习总结,

    MySQL架构 MySQL可分为Server和存储引擎两部分,如图1所示. Server层:包括客户端连接器.查询缓存.解析/预处理器.优化器.执行器等,以及MySQL内置函数和所有跨引擎的功能都在这 ...

  10. [CISCN2019 华北赛区 Day2 Web1]Hack World(二分法写布尔注入脚本)

    记一道布尔注入的题,存在过滤字符. 从题目看应该是一道注入题.提示存在flag表flag列. 输入1和2的返回结果不一样,可能是布尔注入. 简单用万能密码尝试了一下.提示SQL Injection C ...