这篇文章主要讲解了“C#装箱和拆箱是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C#装箱和拆箱是什么”吧!
装箱:将值类型转换为引用类型。
拆箱:将引用类型转换为值类型。
值类型是一种相对轻型的类型,不像对象那样在托管堆中分配,也不会被GC,不通过指针来引用,不过在有些时候需要获取对值类型的引用,例如在使用net1.0的集合类ArrayList的时候。
class Program { static void Main(string[] args) { ArrayList list = new ArrayList(); Point p;//因Point为值类型,分配在堆栈中 for (int i = 0; i < 100; i++) { pp.x = p.y = i; //初始化Point中的成员 list.Add(p);//对p进行装箱后,将引用添加到list中 } } } struct Point { public Int32 x; public Int32 y; }ArrayList的Add方法是接受一个Object参数,如下 public virtual int Add(object value);
所以在执行Add方法时会将Point值类型转换为一个堆得托管对象,并获取到这个对象的引用,将引用地址存储在ArrayList中。
在一个值类型装箱的时候内部发生的事情:
l 在托管堆分配好内存。分配的内存是值类型的各个字段所需内存量加上托管堆上的两个额外成员(类型对象指针和同步索引块)所需的内存量。
l 值类型中的字段值复制到新分配的堆内存中。
l 返回对象的引用地址。
拆箱就是执行和装箱相反的操作,将引用类型转化为值类型。接上面的代码,获取ArrayList中的元素值用如下代码:
for (int j = 0; j < 10; j++) { Point point =(Point)list[j]; Console.WriteLine("X:" + point.x + " Y:" + point.y); }
上面的代码中通过索引取到ArrayList中存储的各个Point的引用地址,通过Point类型转换将其对应的值从堆中复制到Point的实例point中,这个转换的过程就是拆箱的过程。
在拆箱的过程中要注意以下两点:
1. 如果对已装箱的值类型的引用的变量为null,会引发NullRefreenceException异常
2. 如果一个引用指向的对象在拆箱时不是用的装箱时所使用的类型,将会引发InvalidCastException异常。代码如下:
static void Main(string[] args) { Int32 x = 5; Object o = x; Int16 y = (Int16)o;//引发InvalidCastException异常 }
正确的做法是,现将其用Int32类型来拆箱,然后再强制转换为Int16
static void Main(string[] args) { Int32 x = 5; Object o = x; Int16 y = (Int16)(Int32)o; }
下面来看两段程序来深入理解下装箱和拆箱
代码一:
static void Main(string[] args) { Int32 x = 5; Object o = x; x = 123; Console.WriteLine(x + ", " + (Int32)o); }
感谢各位的阅读,以上就是“C#装箱和拆箱是什么”的内容了,经过本文的学习后,相信大家对C#装箱和拆箱是什么这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是编程网,小编将为大家推送更多相关知识点的文章,欢迎关注!