装箱 Or 拆箱

来源:互联网 发布:java内存溢出 问题排查 编辑:程序博客网 时间:2024/05/16 17:48

 

  1.引用、值类型

  在.Net中所有的类型都是由基类System.Object继承过来的,比如我们最常用的int、string类型等,也就是经常说的所有的事物都是对象。而在上一篇中提到过,对象是存放在堆中的,因此所有的类型如果都放在堆中的话会造成效率低下。

  为了解决这种效率低下的问题,因此才有了引用类型和值类型

  值类型:Sbyte、Byte、Short、Ushort、Int、Uint、Long、Ulong、Char、Float、Double、Bool、Decimal)、枚举(enum)、结构(struct)

   引用类型:类、数组、接口、委托、字符串等

   值类型是在栈中初始化的,比如 Int i=3,这会在栈中初始化一个变量。(全局变量将会在数据区,上篇博客有介绍)

   引用类型:引用类型是在堆中初始化的,并且C#中的堆是一个托管堆,会不时的释放一些无用的对象


   2.装箱和拆箱

   通过名称我们也就知道这两个过程是互逆的。

   装箱:将值类型转换为引用类型

   拆箱:将引用类型转换为值类型

   知道了装箱和拆箱的概念,就好理解多了,那么如何将值类型转换为引用类型呢?

   正是由于他们都继承自一个基类(System.Object),因此可以通过此基类来实现转换,下面看一个Demo


   值类型——————引用类型

  

<span style="font-size:18px;"> static void Main(string[] args)        {            //定义一个值类型操作            int i = 1;            //装箱操作            object boxed = i;            //输出结果为1            Console.WriteLine(boxed);        }</span>

   说了半天,看上述代码顿时感觉太简单了,在正是由于他们都继承自System.Object,所以才可以实现装箱操作。整个操作步骤也特别的简单。

  1.在堆上为值类型对象创建一块区域

  2.将栈上值类型变量复制到堆上

  3.将堆上创建的对象的地址给栈上的引用类型的变量


   引用类型——————值类型

<span style="font-size:18px;">   static void Main(string[] args)        {            //定义一个值类型操作            int i = 1;            //装箱操作            object boxed = i;            //拆箱操作            int j = (int)boxed;            //输出结果为1            Console.WriteLine(boxed);        }</span>

   1.获取已装箱对象的地址

   2.将值从堆上的变量中复制到栈上的变量中

   注意:拆箱之前必须先装箱


   3.为什么需要拆箱和装箱

   既然装箱和拆箱如何效率低下,为何还会有呢?这就是为了解决参数化问题,什么意思呢?例如调用一个含类型为Object的参数的方法,正因为类型是Object所以,可以支持任意类型,可以对所有的类型通用。因此如果传入的是值类型时,就需要先装箱。

 

     

 


0 0