浅析C# 装箱和拆箱
Object类型是所有类型的基类,其下面有ValueType类型。什么结构啊,枚举啊,都继承ValueType,这些都是值类型。其他的什么类啊,数组啊,字符串啊等等都是引用类型。
简单的说,直接继承Object的都是引用类型,继承ValueType的都是值类型。
那样的话,像整形这样的结构按理说其实也是间接继承自Object的,那么按照里氏替换原则,整形转换成object应该没有问题吧。
像上面的代码,这个b还是值类型吗?如果是值类型,好像又和直接继承Object都是引用类型矛盾了啊。其实这就是“装箱”。A是值类型,变成b,而成了Object类型,其实就变成了引用类型,简单的说装箱就是将值类型转成引用类型。与之对应的拆箱,将引用类型变成值类型。
那不就是个类型转换吗?还整个什么拆箱和装箱这样难听的名字!
错!值类型和引用类型之间的转换与什么一般的子类转父类,父类转子类不一样,他这种转换可涉及到存储上的变化
double d = 2.8; object obj = d; //装箱操作,要尽量避免装箱 d=(double)obj; //拆箱操作,影响性能,要避免拆箱操作
隐式转换:不需要声明就能转换的转换
int i=221; long j=i;
显式转换:又称“强制转换”
double x=25.0123; int y=(int)x; int y=Convert.ToInt32(x);
装箱:值类型转换为引用类型(隐式转换)
把数据从堆栈“装到”托管堆中
拆箱:引用类型转换为值类型(显式转换)
解释: int i=123;值类型变量i,赋值为123,在内存中,堆栈里边有这样一个空间,把123存进去,变量名i标识这段空间。
Object o=(object)i; 把一个值类型的变量i赋值给object类型的变量o,这样就装箱了。Object类型是引用类型,把一个值类型转换成引用类型就是装箱。在这里我们进行了强制转换,事实上不用强制转换也能装箱,因为object类型是所有数据类型的根父类。
装箱过程在内存中发生了什么事情呢?
首先为o在托管堆中开辟空间,然后把123存进去,那么i就被装箱了
装箱和拆箱是比较耗费性能的,还会引入一些诡异的bug,我们应当避免装箱和拆箱。
为什么需要装箱和拆箱呢?
学习装箱,是为了尽量避免装箱,装箱往往是被迫的。
在C#没有支持泛型之前,为了使某些程序具有通用性,使用到了Object(Object是所有类型的跟父类),所以必须装箱。
对于已装箱的对象,因为无法直接调用其指定方法,所以必须先拆箱,再调用方法,但再次拆箱,会生成新的栈实例,而无法修改装箱对象。这样消耗资源很大!
以上就是浅析C# 装箱和拆箱的详细内容,更多关于c# 装箱和拆箱的资料请关注我们其它相关文章!
相关推荐
-
C#实现装箱与拆箱操作简单实例
本文以一个简单实例讲述了C#装箱和拆箱操作的实现方法,简单来说装箱是将值类型转换为引用类型:拆箱是将引用类型转换为值类型,是涉及栈和堆的使用方面的东西,学过C#的人应该都知道,所以这里就不哆嗦了,本例代码也是面向C#新手的,非常简单. 具体实现代码如下: using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace UnBoxing { class Program {
-
C# 装箱和拆箱的知识回顾
装箱是将值类型转换为 object 类型或由此值类型实现的任何接口类型的一个过程. 当 CLR 对值类型进行装箱时,会将该值包装到 System.Object 内部,再将后者存储在托管堆上. 拆箱将从对象中提取值类型. 装箱是隐式的:拆箱是显式的. 装箱和拆箱的概念是类型系统 C# 统一视图的基础,其中任一类型的值都被视为一个对象. 在下面的示例中,将整型变量 i 进行了装箱并分配给对象 obj. static void Main(string[] args) { var i = 123; //
-
解析C#中的装箱与拆箱的详解
装箱和拆箱是值类型和引用类型之间相互转换是要执行的操作. 1. 装箱在值类型向引用类型转换时发生2. 拆箱在引用类型向值类型转换时发生光上述两句话不难理解,但是往深处了解,就需要一些篇幅来解释了.我们先看装箱时都会发生什么事情,下面是一行最简单的装箱代码 复制代码 代码如下: object obj = 1; 这行语句将整型常量1赋给object类型的变量obj: 众所周知常量1是值类型,值类型是要放在栈上的,而object是引用类型,它需要放在堆上:要把值类型放在堆上就需要执行一次装箱操作.这行
-
C#装箱和拆箱操作实例分析
本文实例讲述了C#装箱和拆箱操作.分享给大家供大家参考,具体如下: 1. C#中的装箱 C#中的装箱就是把一个值类型隐式地转换为object类型,转换过程中采用的是值的拷贝而不是引用,这从下面的例子可以看出: using System; public class Test { public static void Main(String[] args) { int i = 10; //将值类型的i装箱 //需要注意的是:这里的装箱采用的是值的拷贝 object obj = i; //检验是否装箱
-
再议C#中的装箱与拆箱的问题详解
上一篇写了一下装箱拆箱的定义和IL分析,这一篇我们看下使用泛型和不使用泛型引发装箱拆箱的情况1.使用非泛型集合时引发的装箱和拆箱操作 看下面的一段代码: 复制代码 代码如下: var array = new ArrayList();array.Add(1);array.Add(2); foreach (int value in array){Console.WriteLine("value is {0}",value);} 代码声明了一个ArrayList对象,向ArrayList中添
-
C#装箱与拆箱操作的深入讲解
疑问 都知道C#有装箱和拆箱的操作,听闻也都是讲int类型转换成object类型就是装箱,将object类型再转回int类型就是拆箱. 描述的通俗点: 装箱 将值类型转换成引用类型, 拆箱 将引用类型转换成值类型. 那看来是要先了解一下引用类型和值类型了. 引用类型和值类型 在C#中,所有称之为"类(class)"的类型,都是引用类型,而值类型都是标注为结构(struct)或者枚举(enum). 下面就来看一看引用类型和值类型,在实例化的时候发生了什么操作(首先自然是申明一下两种类型了
-
深入理解C# 装箱和拆箱(整理篇)
装箱(boxing)和拆箱(unboxing)是C#类型系统的核心概念.是不同于C与C++的新概念!,通过装箱和拆箱操作,能够在值类型和引用类型中架起一做桥梁.换言之,可以轻松的实现值类型与引用类型的互相转换,装箱和拆箱能够统一考察系统,任何类型的值最终都可以按照对象进行处理. 装箱和拆箱是值类型和引用类型之间相互转换是要执行的操作. 1. 装箱在值类型向引用类型转换时发生 2. 拆箱在引用类型向值类型转换时发生 //1. // 装箱和拆箱是一个抽象的概念 //2. // 装箱是将值类型转换为引
-
浅析C# 装箱和拆箱
Object类型是所有类型的基类,其下面有ValueType类型.什么结构啊,枚举啊,都继承ValueType,这些都是值类型.其他的什么类啊,数组啊,字符串啊等等都是引用类型. 简单的说,直接继承Object的都是引用类型,继承ValueType的都是值类型. 那样的话,像整形这样的结构按理说其实也是间接继承自Object的,那么按照里氏替换原则,整形转换成object应该没有问题吧. 像上面的代码,这个b还是值类型吗?如果是值类型,好像又和直接继承Object都是引用类型矛盾了啊.其实这就是
-
Java 装箱与拆箱详解及实例代码
Java 装箱与拆箱详解 前言: 要理解装箱和拆箱的概念,就要理解Java数据类型 装箱:把基本类型用它们相应的引用类型包装起来,使其具有对象的性质.int包装成Integer.float包装成Float 拆箱:和装箱相反,将引用类型的对象简化成值类型的数据 Integer a = 100; 这是自动装箱 (编译器调用的是static Integer valueOf(int i)) int b = new Integer(100); 这是自动拆箱 看下面一段代码 m1 public class
-
详解Java 自动装箱与拆箱的实现原理
什么是自动装箱和拆箱 自动装箱就是Java自动将原始类型值转换成对应的对象,比如将int的变量转换成Integer对象,这个过程叫做装箱,反之将Integer对象转换成int类型值,这个过程叫做拆箱.因为这里的装箱和拆箱是自动进行的非人为转换,所以就称作为自动装箱和拆箱.原始类型byte, short, char, int, long, float, double 和 boolean 对应的封装类为Byte, Short, Character, Integer, Long, Float, Dou
-
Java中的装箱和拆箱深入理解
自动装箱和拆箱问题是Java中一个老生常谈的问题了,今天我们就来一些看一下装箱和拆箱中的若干问题.本文先讲述装箱和拆箱最基本的东西,再来看一下面试笔试中经常遇到的与装箱.拆箱相关的问题. 一.什么是装箱?什么是拆箱? 在前面的文章中提到,Java为每种基本数据类型都提供了对应的包装器类型,至于为什么会为每种基本数据类型提供包装器类型在此不进行阐述,有兴趣的朋友可以查阅相关资料.在Java SE5之前,如果要生成一个数值为10的Integer对象,必须这样进行: 复制代码 代码如下: Intege
-
C#装箱和拆箱原理详解
.NET包含一个特殊的Object类,可以接受任意的数据类型的值,当所传递或所赋值的类型不是一个特定的数据类型时,object类就提供了一种传递参数和赋值的通用方法.赋给object的值必须作为引用类型,并存放砸托管堆中. 装箱: int age = 24; object refAge= age; 可以看的出,第一条语句创建一个变量age,并将值放在托管栈中: 第二条语句将age的值赋给引用类型.它将值24放在托管堆中. 这个值类型包装为引用类型的过程,称为装箱. 拆箱: 相反,将引用类型转换为
-
浅谈Java自动装箱与拆箱及其陷阱
在本文中,笔者向大家介绍下Java中一个非常重要也非常有趣的特性,就是自动装箱与拆箱,并从源码中解读自动装箱与拆箱的原理,同时这种特性也留有一个陷阱.开发者如果不注意,就会很容易跌入这个陷阱. 自动装箱(Autoboxing) 定义 大家在平时编写Java程序时,都常常以以下方式来定义一个Integer对象: Integer i=100; 从上面的代码中,大家可以得知,i为一个Integer类型的引用,100为Java中的基础数据类型(primitive data type).而这种直接将一个基
-
c#装箱和拆箱知识整理
1.装箱和拆箱是一个抽象的概念 2.装箱是将值类型转换为引用类型 : 拆箱是将引用类型转换为值类型 利用装箱和拆箱功能,可通过允许值类型的任何值与Object 类型的值相互转换,将值类型与引用类型链接起来 例如: 复制代码 代码如下: int val = 100; object obj = val; Console.WriteLine ("对象的值 = {0}", obj); 这是一个装箱的过程,是将值类型转换为引用类型的过程 复制代码 代码如下: int val = 100; obj
随机推荐
- AngularJS 实现点击按钮获取验证码功能实例代码
- wireshark抓取本地回环数据包和取出数据的方法
- Asp.Net中的数据源概述与配置及实例代码
- php 特殊字符处理函数
- php使用mysqli向数据库添加数据的方法
- 只需五句话搞定JavaScript作用域(经典)
- python实现读取命令行参数的方法
- 微信和qq时间格式模板实例详解
- vue实现全选、反选功能
- C语言以数据块的形式读写文件实例代码
- 使用Ruby on Rails快速开发web应用的教程实例
- 艰难完成 nginx + puma 部署 rails 4的详细记录
- Shell根据日期、月份、星期判断年份的代码
- SQL Server 高速缓存依赖分析
- sql清空表数据后重新添加数据存储过程的示例
- Java程序员应该遵守的10条纪律
- 使用XmlSerializer序列化List对象成XML格式(list对象序列化)
- Android 实现扫雷小游戏实例代码
- Android原生侧滑控件DrawerLayout使用方法详解
- Spring Security 控制授权的方法