装箱与拆箱
装箱与拆箱
基础知识:
.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
浙公网安备 33010602011771号