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 类型的 ...
随机推荐
- [小北De编程手记] : Lesson 01 - Selenium For C# 之 环境搭建
在我看来一个自动化测试平台的构建,是一种很好的了解开发语言,单元测试框架,自动化测试驱动,设计模式等等等的途径.因此,在下选择了自动化测试的这个话题来和大家分享一下本人关于软件开发和自动化测试的认识. ...
- mysql服务器的字符集
文章:http://www.cnblogs.com/fantiantian/p/3468454.html 的评论中有这样的文字: 谢谢沧海一滴的总结 在Linux中一般都是UTF-8字符集.我们在建数 ...
- C++ 面向对象的三个特点--多态性(二)
运算符重载 运算符重载,就是对已有的运算符重新进行定义,赋予其另一种功能,以适应不同的数据类型. 类外部的运算符重载 首先,我们通过一个例子来说明为什么要有运算符重载. // Complex.h cl ...
- 【使用 DOM】使用 DOM 元素
1. 使用元素对象 HTMLElement对象提供了一组属性,可以用它们来读取和修改被代表的数据.下表介绍了这些属性. 下面代码展示了如何使用表中所列的一些基本属性. <!DOCTYPE htm ...
- QT5中全屏显示子窗口和取消全屏的方法
问题描述:用QT5做了个MDI多窗体应用程序,想把子窗体全屏显示,用网上的方法,但总是遇到问题. 网上的解决方法原文在这:http://www.cnblogs.com/Rick-w/archive/2 ...
- jQuery源码分析-01总体架构
1. 总体架构 1.1自调用匿名函数 self-invoking anonymous function 打开jQuery源码,首先你会看到这样的代码结构: (function( window, und ...
- anriod TabHost
package com.example.yanlei.mytk; import android.os.Bundle; import android.support.v7.app.AppCompatAc ...
- MacBook Air 使用技巧
1.Finder 相当于资源管理器 Launchpad 相当于桌面 Safari 浏览器 2.快捷键 * cmd+shift+3: 捕获整 ...
- 字符串匹配--Karp-Rabin算法
主要特征 1.使用hash函数 2.预处理阶段时间复杂度O(m),常量空间 3.查找阶段时间复杂度O(mn) 4.期望运行时间:O(n+m) 本文地址:http://www.cnblogs.com/a ...
- JAVA-插入排序
插入排序 package com.pb.string.demo1; /** * 插入排序 * @author Denny * */ public class Demo { public static ...