A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 朱勋 黑马帝   /  2011-10-28 10:19  /  2967 人查看  /  7 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

希望大家都发  表自己的意见

评分

参与人数 1技术分 +1 收起 理由
杨恩锋 + 1

查看全部评分

7 个回复

正序浏览
章坚 黑马帝 2011-11-1 14:23:27
8#
形象地说就是
装箱 即值类型对引用类型的转换   拆箱即 引用类型对值类型的转换
回复 使用道具 举报
黄朝辉 黑马帝 2011-10-28 12:07:31
7#
回复了几次都被审核了,,郁闷!
总之 少装拆箱,有害性能!

评分

参与人数 1技术分 +1 收起 理由
杨恩锋 + 1

查看全部评分

回复 使用道具 举报
装箱是将一个值类型转换成一个引用类型,而拆箱是将一个已装箱的引用类型转换成值类型,二楼的代码完全正确的描述了它的用法,有的时候要往集合比如ArrayList中放入数据,
ArrayList的方法声明为
public virtual int Add(
        Object value
)
它的参数只接收对象类型,不接受值类型,这个时候就需要用到装箱了,也叫上溯造型,拆箱又叫下溯造型,但是下溯造型是不安全的。比如要将二楼代码中的obj下转成bool是错误的。所以拆箱的前提是将一个已装箱的引用类型转换成与它对应的值类型。

评分

参与人数 1技术分 +1 收起 理由
杨恩锋 + 1

查看全部评分

回复 使用道具 举报
一:装箱/拆箱是什么? 装箱:用于在垃圾回收堆中存储值类型。装箱是值类型到 object 类型或到此值类型所实现的任何接口类型的隐式转换。
拆箱:从 object 类型到值类型或从接口类型到实现该接口的值类型的显式转换。

二:为何需要装箱?(为何要将值类型转为引用类型?)
一种最普通的场景是,调用一个含类型为Object的参数的方法,该Object可支持任意为型,以便通用。当你需要将一个值类型(如Int32)传入时,需要装箱。
另一种用法是,一个非泛型的容器,同样是为了保证通用,而将元素类型定义为Object。于是,要将值类型数据加入容器时,需要装箱。

三:装箱/拆箱的内部操作。 装箱:
对值类型在堆中分配一个对象实例,并将该值复制到新的对象中。按三步进行。
第一步:新分配托管堆内存(大小为值类型实例大小加上一个方法表指针和一个SyncBlockIndex)。
第二步:将值类型的实例字段拷贝到新分配的内存中。
第三步:返回托管堆中新分配对象的地址。这个地址就是一个指向对象的引用了。
有人这样理解:如果将Int32装箱,返回的地址,指向的就是一个Int32。我认为也不是不能这样理解,但这确实又有问题,一来它不全面,二来指向Int32并没说出它的实质(在托管堆中)。
拆箱:
检查对象实例,确保它是给定值类型的一个装箱值。将该值从实例复制到值类型变量中。
有书上讲,拆箱只是获取引用对象中指向值类型部分的指针,而内容拷贝则是赋值语句之触发。
四:装箱/拆箱对执行效率的影响 显然,从原理上可以看出,装箱时,生成的是全新的引用对象,这会有时间损耗,也就是造成效率降低。
那该如何做呢?
首先,应该尽量避免装箱。
比如上例2的两种情况,都可以避免,在第一种情况下,可以通过重载函数来避免。第二种情况,则可以通过泛型来避免。
当然,凡事并不能绝对,假设你想改造的代码为第三方程序集,你无法更改,那你只能是装箱了。
对于装箱/拆箱代码的优化,由于C#中对装箱和拆箱都是隐式的,所以,根本的方法是对代码进行分析,而分析最直接的方式是了解原理结何查看反编译的IL代码。比如:在循环体中可能存在多余的装箱,你可以简单采用提前装箱方式进行优化。

回复 使用道具 举报
装箱把值类型转化为引用类型,拆箱把引用类型转化为值类型;值类型保存在内存堆栈上,引用类型保存在内存的托管堆上。
装拆箱比较消耗性能。
回复 使用道具 举报
本帖最后由 李荣壮 于 2011-10-28 11:15 编辑

装箱:
int int1=123;
object obj=(object)int1;
拆箱:
int1=(int)obj;

装箱比较简单,任何继承类都可以转换成它的基类或基类的基类,但是拆箱的时候要注意,如果不能直接或间接继承的,是不能转换的,会报错。
任何类型都可以装成Object类。



评分

参与人数 1技术分 +1 收起 理由
杨恩锋 + 1

查看全部评分

回复 使用道具 举报
装箱把值类型转化为引用类型,拆箱把引用类型转化为值类型;值类型保存在内存堆栈上,引用类型保存在内存的托管堆上。
  1.             int a = 3;
  2.             string b = a.ToString(); //装箱
  3.             a = int.Parse(b); //拆箱
复制代码
反正都是耗性能。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马