【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) { //直接把一个基本类型变量 ...
随机推荐
- scrapy-splash抓取动态数据例子二
一.介绍 本例子用scrapy-splash抓取一点资讯网站给定关键字抓取咨询信息. 给定关键字:打通:融合:电视 抓取信息内如下: 1.资讯标题 2.资讯链接 3.资讯时间 4.资讯来源 二.网站信 ...
- phpcms v9 wap手机门户站点内容页添加上一篇、下一篇的方法
PHP源码修改:打开 phpcms\modules\wap\index.php 文件找到if(!$r || $r['status'] != 99) showmessage(L('info_does_n ...
- (转)Dubbo扩展点实现细节
实现细节 (+) (#) 初始化过程细节 (+) (#) 解析服务 基于dubbo.jar内的META-INF/spring.handlers配置,Spring在遇到dubbo名称空间时,会回调Dub ...
- [ES6] 06. Arrow Function =>
ES6 arrow function is somehow like CoffeeScirpt. CoffeeScript: //function call coffee = -> coffee ...
- 图片转为byte[]、String、图片之间的转换
package com.horizon.action; import java.io.ByteArrayOutputStream; import java.io.File; import java.i ...
- rails执行sidekiq任务的时候报错“can't connect to local mysql server through socket '/var/run/mysqld/mysqld.sock'”
rails执行sidekiq任务的时候报错“can't connect to local mysql server through socket '/var/run/mysqld/mysqld.soc ...
- hadoop权威指南(第四版)要点翻译(4)——Chapter 3. The HDFS(1-4)
Filesystems that manage the storage across a network of machines are called distributed filesystems. ...
- Oracle中查询某字段不为空或者为空的SQL语句怎么写
比如 insert into table a (a1,b1)values("a1",''); 对于这种情况,因为表里存的是'',其实是没有内容的,要查询这个字段,不能直接使用 se ...
- 如何为Drupal缓存对象指定缓存类?
什么意思?意思是说,假如你有这样的需求,需要将cache_page缓存到数据库,其它的都缓存到memcache,这该怎么办? 看看_cache_get_object()的实现你就会知道上面的问题该怎么 ...
- java的日期格式使用
转自: 关于java中六个时间类的使用和区别 java.util.Date java.sql.Date java.sql.Time java.sql.Timestamp java.tex ...