浅析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# 装箱和拆箱的资料请关注我们其它相关文章!

(0)

相关推荐

  • C#装箱与拆箱操作的深入讲解

    疑问 都知道C#有装箱和拆箱的操作,听闻也都是讲int类型转换成object类型就是装箱,将object类型再转回int类型就是拆箱. 描述的通俗点: 装箱 将值类型转换成引用类型, 拆箱 将引用类型转换成值类型. 那看来是要先了解一下引用类型和值类型了. 引用类型和值类型 在C#中,所有称之为"类(class)"的类型,都是引用类型,而值类型都是标注为结构(struct)或者枚举(enum). 下面就来看一看引用类型和值类型,在实例化的时候发生了什么操作(首先自然是申明一下两种类型了

  • C#实现装箱与拆箱操作简单实例

    本文以一个简单实例讲述了C#装箱和拆箱操作的实现方法,简单来说装箱是将值类型转换为引用类型:拆箱是将引用类型转换为值类型,是涉及栈和堆的使用方面的东西,学过C#的人应该都知道,所以这里就不哆嗦了,本例代码也是面向C#新手的,非常简单. 具体实现代码如下: using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace UnBoxing { class Program {

  • 再议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# 装箱和拆箱(整理篇)

    装箱(boxing)和拆箱(unboxing)是C#类型系统的核心概念.是不同于C与C++的新概念!,通过装箱和拆箱操作,能够在值类型和引用类型中架起一做桥梁.换言之,可以轻松的实现值类型与引用类型的互相转换,装箱和拆箱能够统一考察系统,任何类型的值最终都可以按照对象进行处理. 装箱和拆箱是值类型和引用类型之间相互转换是要执行的操作. 1. 装箱在值类型向引用类型转换时发生 2. 拆箱在引用类型向值类型转换时发生 //1. // 装箱和拆箱是一个抽象的概念 //2. // 装箱是将值类型转换为引

  • 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# 装箱和拆箱

    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

随机推荐