C#装箱和拆箱

值类型和引用类型的基础知识

先举个例子,假如你现在在读一份报纸,为了给朋友一份,将报纸的全部内容复印了一份并交给他。他获得了一份属于自己的完整报纸。在这种情况下,我们处理的是值类型行为,所有的信息都掌握在自己手里,不需要从其他地方获取,你和朋友手中的是各自独立的,你在自己的报纸上添加注释,朋友的报纸上不会看见。

再假设你现在再看一个网页,与之前相比这次你给朋友的只是一个网页的Url,这种情况下,几时引用类型行为,Url代替了引用。为了能看到网页,需要在浏览器的输入Url来加载,假如网页由于某种原因需要改变,下次你个朋友打开的网页都会看到改变后的网页。

通过上面的例子应该会好理解一些,值类型和引用类型,两者之间本来没有多大的联系,设计人员通过一种名为装拆箱的操作,使得这两种类型创建了新的联系,让和任何 值类型都可以当成对象引用类型来操作。在C#中梳理了一下这两种类型

值类型:整型int;长整型long;浮点型float;字符型 char;布尔型bool;枚举 enum;结构 struct;他们统一继承ValueType

引用类型:数组,自定义类,委托,object,接口,字符串等;

装箱和拆箱

装箱:值类型转化为引用类型的过程。在堆上为新生成的引用对象分配内存,然后将值类型的数据拷贝到分配的内存中,返回堆中新分配对象的地址,这个地址就是指向对象的引用(如下图)

拆箱:引用类型转化为值类型的过程。获取引用类型的地址,将用用对象的值拷贝到栈上的值类型实例中(注意 拆箱时可能会引发“转换无效”的异常。要记住,拆箱时强转的值类型,应以装箱时的值类型一致)

装箱时 i是值类型的变量,o是引用类型的变量。将i的值赋给o有道理吗?o的值必须是一个引用,而数字10不是引用,它是一个整数值。实际发生的事情就是装箱:运行时将在堆上创建一个包含值(10)的对象(它是一个普通对象)。o的值是对该新对象的一个引用。该对象的值是原始值的一个副本,改变i的值不会改变箱内的值。

相反的操作—拆箱。必须告诉编译器将object拆箱成什么类型。如果使用了错误的类型(比如ob原先被装箱成unit或者long,或者根本就不是一个已装箱的值),就会抛出一个InvalidCastException异常。同样,拆箱也会复制箱内的值,在赋值之后,m和该对象之间不再有任何关系。

通过上述的原理可以看出,装拆箱分配内存和拷贝数据会影响性能的操作,尽量避免装拆箱。

  • 6
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值