【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) { //直接把一个基本类型变量 ...
随机推荐
- 关于Java设计模式的一些概况
设计模式(Design pattern)在软件行业一直都扮演着很重要的角色.最近感觉自己对设计模式的知识有些遗忘了,虽然以前也看了很多,但是坦白说,其实并没有怎么理解.基本还是为了应付面试.然后,在工 ...
- socket连接和http连接的区别
socket连接和http连接的区别 HTTP协议:简单对象访问协议,对应于应用层 ,HTTP协议是基于TCP连接的 tcp协议: 对应于传输层 ip协议: 对应于网络层 TCP/IP ...
- Android源代码编译apk导入第三方包报错
报错内容例如以下: make: *** 没有规则能够创建"out/target/common/obj/APPS/ AndroidWFS_intermediates/classes-full- ...
- (转)intellij idea svn 修改文件后,父文件夹也标注修改
svn文件修改后,默认只有当前文件更改而父文件没有标注,很不直观:查了一顿后,发现,可以设置: File—->settings—->version control—–>勾选show ...
- python处理csv
python处理csv 学习了:https://blog.csdn.net/qq_33363973/article/details/78783481 竟然pip install csv 无果: 学习 ...
- Android-自己定义PopupWindow
Android-自己定义PopupWindow 2014年5月12日 PopupWindow在应用中应该是随处可见的,非经常常使用到,比方在旧版本号的微信其中就用到下拉的PopupWindow.那是自 ...
- 一个简单的int型C++单链表的实现
IntSLList.h //************************ intSLList.h ************************** // singly-linked list ...
- windows Server2012 之 IIS8.0配置安装完整教程
IIS8.0是windows Server2012自带的服务器管理系统,和以往不同,IIS8.0安装和操作都比较简单,界面很简洁,安装也很迅速.今天我们重点完整的演示下Internet Informa ...
- vue - for 遍历对象和遍历对象数组
1. 遍历对象时,参数: 第一个为值,第二个为键名,第三个为索引 <!DOCTYPE html> <html lang="en"> <head> ...
- Manual close is not allowed over a Spring managed SqlSession(转)
最近用junit测试spring项目的时候,报错: Manual close is not allowed over a Spring managed SqlSession 意思是不允许手动关闭spr ...