box unboxing(装箱 拆箱) C#编程指南
什么是箱
箱是指托管堆,装箱指在托管堆中将栈上的值类型进行封装,生成一份该值类型对象的副本,并返回该副本的地址。
而拆箱是返回已装箱值类型在托管堆中的地址(严格意义来讲:拆箱是不包括值类型字段的拷贝的)
值类型和引用类型是在不同的堆和栈上的,箱的操作,涉及数据的拷贝和内存的分配,所以引用性能的消耗
关于装箱和拆箱的几个问题
1.什么是拆箱和装箱?
装箱就是值类型转换为引用类型,拆箱就是引用类型(被装箱的对象)转换为值类型。
2.什么是箱子?
就是引用类型对象。
3.箱子放在哪里?
托管堆上。
4.装箱和拆箱有什么性能影响?
装箱和拆箱都涉及到内存的分配和对象的创建,有较大的性能影响。
5.如何避免隐身装箱?
编码中,多使用泛型、显示装箱。
6.箱子的基本结构?
上面说了,箱子就是一个引用类型对象,因此她的结构,主要包含两部分:
- 值类型字段值;
- 引用类型的标准配置,引用对象的额外空间:TypeHandle和同步索引块,关于这两个概念在本系列后面的文章会深入探讨。
7.装箱的过程?
- 1.在堆中申请内存,内存大小为值类型的大小,再加上额外固定空间(引用类型的标配:TypeHandle和同步索引块);
- 2.将值类型的字段值(x=1023)拷贝新分配的内存中;
- 3.返回新引用对象的地址(给引用变量object o)
8.拆箱的过程?
- 1.检查实例对象(object o)是否有效,如是否为null,其装箱的类型与拆箱的类型(int)是否一致,如检测不合法,抛出异常;
- 2.指针返回,就是获取装箱对象(object o)中值类型字段值的地址;
- 3.字段拷贝,把装箱对象(object o)中值类型字段值拷贝到栈上,意思就是创建一个新的值类型变量来存储拆箱后的值;
box(装箱)消耗大
box在堆栈中创建一个新的对象,性能消耗大
int i = 123;
// Boxing copies the value of i into object o.
object o = i;
过程
1、分配内存:在托管堆中分配好内存,内存的大小是值类型的各字段需要的内存量加上托管堆的所有对象都有的两个额外成员类型对象指针和同步块索引所需要的内存量之和。
2、复制对象:将值类型的字段复制到新分配的内存中
3、返回地址:将已装箱的值类型对象的地址返回给引用类型的变量

unboxing(拆箱)
- 检查对象实例
- 将该值从实例复制到值类型变量中
int i = 123; // a value type
object o = i; // boxing
int j = (int)o; // unboxing
过程
1、检查对象:检查类型是否为null,如果为空则抛出异常
2、返回地址:在堆中找到要拆箱对象的地址
3、数据拷贝:把object中的值类型字段拷贝到栈中,创建一个新的值对象来保存拷贝的值。

如何避免装箱拆箱
使用重载方法,方法的参数提供不同的类型。
使用泛型,在.Net中有泛型集合,比如:ArrayList使用泛型集合:(List<T>) 来避免box,Hashtable对应着Dictionary<TKey, Tvalue>
如果在循环中会有某个值进行装箱,可以在循环外先装箱,避免在循环中装箱。
调用值类型的ToString()方法不会引起装箱。
文档资料
http://msdn.microsoft.com/zh-cn/library/yz2be5wk.aspx
http://msdn.microsoft.com/zh-cn/library/ms173196.aspx
详细解释:.NET面试题解析(02)-拆箱与装箱
box unboxing(装箱 拆箱) C#编程指南的更多相关文章
- MSIL实用指南-装箱拆箱
本篇讲述怎样装箱拆箱.装箱和拆箱都是针对值类型而言的,装箱的性能开销远比拆箱的性能开销大. 装箱装箱指令是Box.使用格式是 ILGenerator.Emit(OpCodes.Box,<值类型& ...
- JAVA的自动装箱拆箱
转自:http://www.cnblogs.com/danne823/archive/2011/04/22/2025332.html 蛋呢 的空间 ??什么是自动装箱拆箱 基本数据类型的自动装箱(a ...
- NET中的类型和装箱/拆箱原理
谈到装箱拆箱,DebugLZQ相信给位园子里的博友一定可以娓娓道来,大概的意思就是值类型和引用类型的相互转换呗---值类型到引用类型叫装箱,反之则叫拆箱.这当然没有问题,可是你只知道这么多,那么Deb ...
- Java 装箱 拆箱
Java 自动装箱与拆箱 ??什么是自动装箱拆箱 基本数据类型的自动装箱(autoboxing).拆箱(unboxing)是自J2SE 5.0开始提供的功能. 一般我们要创建一个类的对象的时候,我 ...
- C#装箱拆箱
. 装箱和拆箱是一个抽象的概念 2. 装箱是将值类型转换为引用类型 :拆箱是将引用类型转换为值类型 利用装箱和拆箱功能,可通过允许值类型的任何值与Object 类 ...
- Java之集合初探(二)Iterator(迭代器),collections,打包/解包(装箱拆箱),泛型(Generic),comparable接口
Iterator(迭代器) 所有实现了Collection接口的容器都有一个iterator方法, 用来返回一个实现了Iterator接口的对象 Iterator对象称作迭代器, 用来方便的实现对容器 ...
- 理解JDK1.5的自动装箱拆箱
JDK1.5的升级引入了装箱和拆箱概念,简单说就是为了简化书写. JDK1.5之前,创建Integer对象是需要这么写的 Integer i = new Integer("3") ...
- CLR via C# 中关于装箱拆箱的摘录
装箱: 为了将一个值类型转换成一个引用类型,要使用一个名为装箱(boxing)的机制.下面总结了对值类型的一个实例进行装箱操作时在内部发生的事情. 1.在托管堆中分配好内存.分配的内存量是值类型的各 ...
- c#学习系列之装箱拆箱
1. 装箱和拆箱是一个抽象的概念 2. 装箱是将值类型转换为引用类型 :拆箱是将引用类型转换为值类型 利用装箱和拆箱功能,可通过允许值类型的任何值与Object 类型的 ...
随机推荐
- dbcp 1.4 底层连接断开时内存泄露bug
在dbcp 1.4中,如果底层的连接已经与数据库断开了,此时dbcp 1.4的实现并不释放内部连接,虽然早已提供了removeAbandoned和removeAbandonedTimeout参数,但是 ...
- NullPointerException at android.widget.AbsListView.obtainView at android.widget.ListView.makeAndAddView
使用ExpandableListView的时候,报如下错.网上搜索发现原来是在CommonNumberQueryAdapter的getGroupView()方法里返回的是null,注意细节哦!!! 1 ...
- Linux学习笔记(整理记录)
1.安装 (1):安装网址:http://www.jb51.net/os/78318.html 2.鸟哥的Linux命令学习 (1):显示系统目前所支持的语言:echo $LANG (2):修改语言成 ...
- ASP.Net页面刷新后自动滚动到原来位置
在网上搜索之后总结了三种方式: 1.设置Page中的MaintainScrollPositionOnPostback属性为true A>.页面里有MaintainScrollPositionOn ...
- AE用线来分割线面(C#2010+AE10.0… .
希望指正. 在 ITools 类中,部分方法如下: public override void OnMouseDown(int Button, int Shift, int X, int Y) { if ...
- JSP page指令详解
JSP指令用来设置整个JSP页面相关的属性,如网页的编码方式和脚本语言. 语法格式如下: <%@ directive attribute="value" %> 指令可以 ...
- Struts2(十)OGNL标签二与Struts2标签
一.Struts2标签的优势 标签库简化了用户对标签的使用 结合OGNL使用,对于集合.对象的访问功能非常强大 提供可扩展的主题.模板支持.极大简化了视图页面的编写 不依赖任何表现层技术 Struts ...
- IOS酷炫的下拉刷新链接收集
https://github.com/MartinRGB/Replace-iOS https://github.com/coolbeet/CBStoreHouseRefreshControl http ...
- Python 常用函数time.strftime()简介
time.strftime()可以用来获得当前时间,可以将时间格式化为字符串等等 格式命令列在下面:(区分大小写) %a 星期几的简写%A 星期几的全称%b 月分的简写%B 月份的全称%c 标准的 ...
- Oracle 数据库二 基本查询
查询当前用户:show user 查看当前用户下的表:select *from tab; 设置行宽: show linesize;(查看行宽) set linesize 120;(设置行宽) ...