装箱与拆箱

装箱与拆箱

基础知识:

.Net的类型

值类型(Value Type )

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

引用类型(Reference Type)

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

值类型与引用类型有什么关系(继承System.Object,同一个祖宗):

System.Object类是所有类型的根,任何类(值类型或引用类型)都是显式或隐式的继承于System.Object;

有什么区别

值类型数据是分配在栈中,而引用类型数据分配在堆上。

 

 

 

装箱与拆箱

装箱:把一个值类型数据放到堆上,就需要装箱操作;

拆箱把一个放在堆上的值类型数据取出来,则需要进行拆箱操作。

 

装箱说明:

int i = 123;

object o = (object)i;

对值类型在堆中分配一个对象实例,并将该值复制到新的对象中。

按三步进行。 

第一步:新分配堆内存(大小为值类型实例大小加上一个方法表指针和一个SyncBlockIndex)。 
第二步:将值类型的实例字段拷贝到新分配的内存中。 
第三步:返回堆中新分配对象的地址。这个地址就是一个指向对象的引用了。

 

 

 

我们通过这种方式将一个值类型的int i装箱为一个object类型的 o变量

 

拆箱说明

int i = 123;

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

int b=int(object)//拆箱

就是一个逆过程了.将一个object 类型的o变量还原为int型的i变量,它进行了如下操作:

(1)环境须先判断堆栈上指向合法对象的地址,以及在对此对象向指定的类型进行转换时是否合法,如果不合法,就抛出异常;

(2)当判断类型转换正确,就返回一个指向对象内的值的指针。

针对上面的合法性判断,有两点需要我们注意:

(1)包含已装箱的值类型的引用的变量如果为null,就抛出一个NullReferenceException异常。

(2)如果引用指向的对象不是所要求的值类型的一个已装箱的实例,就抛出一个InvaildCastException异常

影响:

 

装箱影响

1.0:生成一个全新的引用对象,这会有时间损耗,也就是造成效率降低

2.0:堆上分配的内存资源,需要GC来回收,从而降低程序效率

 

实例说明:

class Program

    {

        static void Main(string[] args)

        {

 

            int a = 0;//分配在栈上

            //隐式装箱

            object b = a;

            //显式拆箱

            int j = (int)b;

            //包含已装箱的值类型的引用的变量如果为null,就抛出一个NullReferenceException异常。

            object o= null;

            int oo = (int)o;

            //如果引用指向的对象不是所要求的值类型的一个已装箱的实例,就抛出一个InvaildCastException异常

            object p = "我是字符串引用类型";

            int pp = (int)p;

        }

    }

 

参考地址:https://www.cnblogs.com/zhangyubao/p/7016910.html

posted on 2020-07-27 11:36  高达  阅读(130)  评论(0)    收藏  举报

导航