装箱和拆箱。享元对象

 装箱、拆箱(取消装箱)装箱(boxing)是隐式的将一个值型转换为引用型对象。 拆箱(unboxing)就是将一个引用型对象转换成合适值型,一般是对装箱的变量进行拆箱。 ­

装箱和取消装箱使值类型能够被视为对象。对值类型装箱将把该值类型打包到 Object 引用类型的一个实例中。这使得值类型可以存储于垃圾回收堆中。取消装箱将从对象中提取值类型。在此示例中,整型变量 i 被“装箱”并赋值给对象 o。 ­

int i = 1; object o = 5; // boxing,装箱可以隐式类型转换 ­­

然后,可以对对象 o取消装箱并将其赋值给整型变量 i: i = (int)o; // unboxing此时i=5,取消装箱是要显示强制类型转换的 ­

 

相关知识: C#程序的运行是在把程序代码加载到内存之后,而程序中的变量、方法在内存存放的区域是不同的,这有助于程序更高效率的运行。C#的值型包括枚举(enum),结构(structure)和基本类型(int, float, short等),是存放在栈里的,值型不需要Garbage Collection来回收占用的内存。超出了作用范围后,系统会自动释放。引用类型(一般就是只的类类型)在堆中分配内存,ky初始化为null。引用型是需要Garbage Collection来回收内存的。 ­

什么是堆?什么是堆栈? heap:是由malloc之类函数分配的空间所在地。地址是由低向高增长的。 stack:是自动分配变量,以及函数调用的时候所使用的一些空间。地址是由高向低减少的。 ­

1、堆区(heap) — 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表,存放的是不知道大小的一些类型。 ­ ­

2、栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。存放的是知道大小的一些类型如int、char类型。 ­

3、全局区(静态区)(static)—,全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。 - 程序结束后由系统释放 ­

4、文字常量区 —常量字符串就是放在这里的。 程序结束后由系统释放 ­

5、程序代码区—存放函数体的二进制代码。

­

装箱与拆箱是.Net2.0的新特性之一。它允许我们把一个值类型变成引用类型,反之亦然。 ­

恩,?这里用一张图来说明:所有的值类型的数据都是存放在栈中;所有的引用类型的数据都是存放在堆中,对于该引用类型的引用地址则存放在栈中。 ­

举例: ­

int x = 0; ­

Int32 y = new Int32(); ­

Object o ; ­

o = x; //隐式的装箱。 ­

o = (Int32)y; //显示的装箱。 ­

恩~,对于装箱而言,是不存在任何疑问点,既可以用显示(Explicit),也可以用隐式(Implicit)。 ­

但是对于拆箱而言,这里有一个断言~!拆箱必须是显示的,而不是隐式的。即: ­

x = o; //Error; ­

x = (int)o 或者 x = (Int32)o; //Right; ­

恩~,这里还有一个问题,对于不同类型的拆箱。存在这样一种形式: ­

Int32 x = 5; ­

Int64 y = 6; ­

object o; ­

o = x; or o = (Int32)x; ­

y = (Int64)o; //It's Error. ­

恩~我会觉得将一个Int32的类型转换成Int64是没有我问题的,但是我错了。这不是转换类型,这是一个拆箱的过程,应该怎么理解,它告诉编译器讲这个object以Int64的方式拆箱赋值给另一个Int64的对象。那显然这是错的。因为还有一个断言是这样的:装箱的类型必须与拆箱的类型一致。而不是什么可隐式转换之类的。所以装箱的时候用的是Int32,拆箱的时候必须是Int32。 ­

那如果我一定要将x转换成Int64呢?可以在拆箱之后再进行类型转换。 ­

y = (Int64)(Int32)o; //第一个是拆箱,第二个是类型转换。­。

享元模式(flyWeight):就是在对一些数据中对于相同类型的数据用同一个变量表示,然后靠名称和内存的位置不同来区别,而不同的数据则一次声明。

你可能感兴趣的:(装箱和拆箱。享元对象)