【c#】装箱与拆箱
从内存执行的角度来看,值类型的内存分配在线程的堆栈上,而引用类型的内存分配在托管堆上。因此从值类型向引用类型的转换,势必牵涉到数据的拷贝与指针引用等操作。
装箱操作,大致过程为:在托管堆中分配新对象的内存,将值类型的字段拷贝到该内存中,然后返回该对象的地址,这样就完成了从值类型到引用类型的转变;拆箱操作,则是获取已装箱对象中来自值类型部分字段的地址。装箱与拆箱并非完全对称的互逆操作,拆箱并不包含字段的拷贝。
概念雷区:
- 装箱与拆箱不是完全对等的互逆操作。从内存的角度上看,拆箱的性能开销远小于装箱,只是在实际的执行中,拆箱之后常伴随着字段的拷贝,以c#为例,编译器总是自动产生拆箱之后的字段拷贝。
- 只有被装箱过的对象才能被拆箱,非所有的引用类型。将非装箱而来的引用类型强制转换为值类型,会抛出InvalidCastException异常。
分拆
值类型,提供了轻量型的数据结构,具有较少的内存开销,对系统性能有明显的作用。而缺点是:缺省方法表指针,因为无法在期望System.Object或其继承类的方法上调用值类型。
装箱过程解析
- 内存分配:在托管堆中分配内存空间,内存大小为欲装箱值类型的大小加上其他额外的内存空间,主要包括方法表指针与SyncBlockIndex,此两个成员用于CLR管理引用类型对象。
- 实例拷贝:将值类型的字段拷贝到新分配的内存中去
- 地址返回
拆箱过程解析
- 实例检查:首先检查是否是null,若是抛出NullReferenceException;若非,检查对象实例,确保是给定值类型的装箱值,并且保证拆箱后的类型为原来的同一类型,否则会抛出InvalidCastException
- 指针返回:返回已经装箱对象中属于原值类型部分字段的地址。而附加成员:方法表指针与SyncBlockIndex对该指针是不可见的。
- 字段拷贝:将托管堆中实例的字段拷贝到线程的堆栈中。
性能
- 在实际的项目中留意发生隐式装箱的可能,并提供相应的多个重载方法来避免装箱的发生。
- 装箱与拆箱经常是以隐式发生的,在系统中显式的实现装箱操作,是提高性能的较好选择
- 泛型能有效减少了装箱与拆箱的发生,大大提高了系统的性能与稳定。
应用
- ArrayList与Array
- Hashtable
- 枚举
枚举类型为典型的.Net值类型,可以被装箱为System.Object,System.ValueType和System.Enum,以及System.Enum实现的三个接口类型System.IComparable,System.IConvertible,System.IFormattable - 关注不经意的隐式转换
public static void Main()
{
int i = ;
//装箱
i.GetType();
//未装箱
i.ToString();
//显式装箱
object o = i;
Hashtable ht = new Hashtable();
ht.Add("One", o);
ht.Add("Two", o);
}GetType方法由System.Object类型提供,因此值类型调用时必须执行装箱操作;而ToString方法则由int类型覆盖,因此不会装箱。Hashtable的Add方法接受System.Object类型的参数,因此通过显式的类型转换来减少隐式的装箱操作。
【c#】装箱与拆箱的更多相关文章
- C#基础回顾(二)—页面值传递、重载与重写、类与结构体、装箱与拆箱
一.前言 -孤独的路上有梦想作伴,乘风破浪- 二.页面值传递 (1)C#各页面之间可以进行数据的交换和传递,页面之间可根据获取的数据,进行各自的操作(跳转.计算等操作).为了实现多种方式的数据传递,C ...
- 【译】.NET中六个重要的概念:栈、堆、值类型、引用类型、装箱和拆箱
为何要翻译 一来是为了感受国外优秀技术社区知名博主的高质量文章,二来是为了复习对.NET技术的基础拾遗达到温故知新的效果,最后也是为了锻炼一下自己的英文读写能力.因为是首次翻译英文文章(哎,原谅我这个 ...
- Java暗箱操作之自动装箱与拆箱
我以前在写Android项目的时候,估计写得最多最熟练的几句话就是: List<Integer> list = new ArrayList<Integer>(); list.a ...
- java 自动装箱自动拆箱
1.Java数据类型 在介绍Java的自动装箱和拆箱之前,我们先来了解一下Java的基本数据类型. 在Java中,数据类型可以分为两大种,Primitive Type(基本类型)和Reference ...
- Java 自动装箱与拆箱
Java 自动装箱与拆箱(Autoboxing and unboxing) 什么是自动装箱拆箱 基本数据类型的自动装箱(autoboxing).拆箱(unboxing)是自J2SE 5.0开始提供 ...
- .NET中六个重要的概念:栈、堆、值类型、引用类型、装箱和拆箱 (转)
作者: Edison Chou 来源: 博客园 发布时间: 2014-09-03 15:59 阅读: 318 次 推荐: 2 原文链接 [收藏] 原文作者:Shivprasad k ...
- .NET中的六个重要概念:栈、堆、值类型、引用类型、装箱和拆箱
为何要翻译 一来是为了感受国外优秀技术社区知名博主的高质量文章,二来是为了复习对.NET技术的基础拾遗达到温故知新的效果,最后也是为了锻炼一下自己的英文读写能力.因为是首次翻译英文文章(哎,原谅我这个 ...
- 深入剖析Java中的装箱和拆箱
深入剖析Java中的装箱和拆箱 自动装箱和拆箱问题是Java中一个老生常谈的问题了,今天我们就来一些看一下装箱和拆箱中的若干问题.本文先讲述装箱和拆箱最基本的东西,再来看一下面试笔试中经常遇到的与装箱 ...
- 转 C# 装箱和拆箱[整理]
1. 装箱和拆箱是一个抽象的概念 2. 装箱是将值类型转换为引用类型 :拆箱是将引用类型转换为值类型 利用装箱和拆箱功能,可通过允许值类型的任何值与Object 类型的 ...
- 《Java中的自动装箱和拆箱功能.》
//Java中的自动装箱和拆箱功能. class AutoboxingUnboxing { public static void main(String[] args) { //直接把一个基本类型变量 ...
随机推荐
- UITabBarControlller 和 UINavigationController
- SQL手工注入小结
第一步先把IE菜单=>工具=>Internet选项=>高级=>显示友好 HTTP 错误信息前面的勾去掉.否则,不论服务器返回什么错误,IE都只显示为HTTP 500服务器错误, ...
- [GLSL]着色器周记02——火焰特效 【转】
http://www.cnblogs.com/tkgamegroup/p/4214081.html 这周学了好多.包括伪随机数.柏林噪声.先说伪随机数.伪随机数我们用的是周期函数而不是那种由前一项乘一 ...
- RenderMonkey 练习 第五天 【OpenGL NormalMapping】
1. 新建一个OpenGL 空effect; 2. 添加相关变量 右击Effect节点选择Add Variable->float->float / float3 添加镜面光强度.灯光位置和 ...
- IIS服务器与web.config配置优化指南
摘自: http://www.3lian.com/edu/2012/11-13/43890.html .修改IIS最大工作进程数 a. 请考虑以下几点: .每一个工作进程都会消耗系统资源和CPU占用率 ...
- [Python爬虫] 之十:Selenium +phantomjs抓取活动行中会议活动
一.介绍 本例子用Selenium +phantomjs爬取活动树(http://www.huodongshu.com/html/find_search.html?search_keyword=数字) ...
- Maven仓库设置代理
线上服务器是没有外网环境的, 添加代理配置如下: <settings> ... <proxies> <proxy> &l ...
- 以JPanel为基础实现一个图像框
代码: import java.awt.Graphics; import javax.swing.ImageIcon; import javax.swing.JPanel; public class ...
- mysql 严格模式取消 group by 和 date zore
取消单个库的时间严格模式 set global sql_mode=(select replace(@@sql_mode,'NO_ZERO_IN_DATE,NO_ZERO_DATE',''));
- Openerp开发进销存系统完毕总结
转自:http://blog.csdn.net/heartrude/article/details/9142463 安装Openoffice 在openoffice中安装openerp repor ...