装箱(Boxing)和拆箱(Unboxing)

装箱(Boxing)和拆箱(Unboxing
                              --自己总结的,有说的不好的地方,请指出

一、在说装箱和拆箱之前得先说一下变量的类型。

C#支持两种变量类型:值类型和引用类型。其中:值类型是指那些基本数据类型。如intdoublechar和用struct声明的用户定义类型等;而引用类型指从基本类型构造而来的类和其它复杂数据类型。

值类型变量保存的是类型的实例,而引用类型的变量保存的不是类型的实例,保存的是实例的引用。

举个例子:创建两个值类型变量ij

int i=7;

int j=i;

则它们在内存中是独立保存的,值类型的变量之间没有任何联系。如果我们改变某一个值,另一个值不会有任何影响。

下面看一下引用类型的变量的情况:

我们声明并实例化下面两个变量:

myClass Class_A=new myClass();

myClass Class_B=Class_A;

它们在内存中的保存方式如下:  

假设在位置0X80000保存类的实例,Class_A保存的是对类实例的引用,即保存的是地址0X80000,Class_B是对Class_A的独立引用,但保存的也是对类实例的引用。

因为类在C#中是引用类型,所以Class_A称为对myClass的引用。第一行代码先在内存中创建myClass的一个实例,并且将Class_A设置为引用该实例。因此,当将Class_A的值赋给Class_B时,Class_B保存的也是该类的实例的引用。如果我们改变Class_A中的属性,则Class_B中也会反映这些改变。

清楚了值类型和引用类型,下面就该说说装箱和拆箱了。

二、装箱和拆箱

将值类型转换为引用类型的过程称为装箱;将引用类型转换为值类型的过程称为拆箱。

2.1 装箱:

如下代码所示:

int i=123;

//object所有其他类型的基本类型,代表的类是System.Object

object o=(object) i;     //装箱

 

装箱的过程是:将i=123复制一份放入堆中,在栈中创建一个object oo保存的是堆中存放i=123的地址。如下图所示:

2.1 装箱的变化过程

 

下面看个例子:

Using System;

Class TestBoxing

{

    Public static void Main ()

    {

        int i=123;

        object 0=i;

        i=456;

        Console.WriteLine(“The value-Type value = {0}”,i);

        Console.WriteLine(“The object-Type value = {0}”,o);

    }

}

 

Output:

The value-Type value =456

The object-Type value =123

 

2.2 拆箱

拆箱的过程基本类似.

如下代码所示:

int i=123;

object o=(object) i;     //装箱

int j=(int) o;          //拆箱

 

过程如下图所示:

2.2 拆箱的变化过程

拆箱的时候要注意:隐式转换的类型要跟装箱前的类型相同,否则会有异常产生。

 

三、总结

C# 将所有的基本数据类型都表示为对象(object),所以按照基本数据类型(object)来调用对象方法是可行的。借助于自动装箱拆箱,可以达到此目的。所以理解装箱和拆箱就很有必要了。但是按照基本数据类型来调用对象方法有一些问题或者说缺点,例如:会造成很多垃圾内存,还会使程序的效率下降等。

C2.0中引入了新的语法规则――泛型(我认为是C#升级中最大的改进^_^),它很好地解决了这些问题。过些日子我会总结一下我对泛型的一些认识,希望能对看到我的博客的朋友们有些帮助。

 

你可能感兴趣的:(in)