C#装箱和拆箱

it2024-05-08  44

文章目录

C#装箱和拆箱题记:何为装箱和拆箱?

C#装箱和拆箱

题记:

最近一个研究项目,需要分解C#写的一个工程软件。只好从头回顾下C#语言的特色。其中一项内容就是对C#装箱和拆箱的认识和理解。拙笔写一篇博客来记录一番。

何为装箱和拆箱?

想必大家都见识过和“装集装箱柜”吧,把一大堆的货物先纸箱或者托盘打包,然后整齐地放进集装箱柜。C#这里的装箱指的是把不同类型的数据打包成在一起。 来看标准的手册定义:

装箱是将值类型转换为“ object 类型或由此值类型实现的任何接口类型”的过程。 比较拗口是吧,简而言之,就是:

装箱 就是把“值类型”转换成“引用类型”(Object);

顾名思义,

拆箱 就是把“引用类型”转换成“值类型”;

下例将整型变量 i 进行了装箱并分配给对象 o。

int i = 123; // The following line boxes i. object o = i;

然后,可以将对象 o 取消装箱并分配给整型变量 i:

o = 123; i = (int)o; // unboxing

众所周知在c#中有两种基本类型,它们分别是值类型和引用类型;而每种类型都可以细分为如下类型:

读者稍微都点C语言知识的话,必定知道“引用”的意思,就是传地址的意思。值类型通常被人们称为轻量级的类型,值类型的实例大多分配在栈上。而所有的引用类型的实例都分配在托管堆上。

先看下如下的示例:

class TestBoxing { static void Main() { int i = 123; // Boxing copies the value of i into object o. object o = i; // Change the value of i. i = 456; // The change in i doesn't affect the value stored in o. System.Console.WriteLine("The value-type value = {0}", i); System.Console.WriteLine("The object-type value = {0}", o); } } /* Output: The value-type value = 456 The object-type value = 123 */

此示例使用装箱将整型变量 i 转换为对象 o。 存储在变量 i 中的值从 123 更改为 456,然而对象o的值仍为123 该示例表明原始值类型和装箱的对象使用不同的内存位置,值类型在栈上,而引用类型是在堆上创建的。因此能够存储不同的值。

装箱,是在垃圾回收堆中存储类型。对值类型装箱会在堆中分配一个对象实例,并将该值复制到新的对象中。

int i = 123; // Boxing copies the value of i into object o. object o = i;

上面的语句形象地用图来表示就是: 再来了解下拆箱

下面的语句演示装箱和取消装箱两种操作:

int i = 123; // a value type object o = i; // boxing int j = (int)o; // unboxing

下图演示了上述语句的结果: 注意:拆箱时,被拆箱的必须是对一个对象的引用。否则会导致 NullReferenceException,如果拆箱的类型不兼容,会导致InvalidCastException 。

下面的示例演示无效的拆箱及引发的 InvalidCastException。 使用 try 和 catch,在发生错误时显示错误信息。

class TestUnboxing { static void Main() { int i = 123; object o = i; // implicit boxing try { int j = (short)o; // attempt to unbox System.Console.WriteLine("Unboxing OK."); } catch (System.InvalidCastException e) { System.Console.WriteLine("{0} Error: Incorrect unboxing.", e.Message); } } }

此程序输出: Specified cast is not valid. Error: Incorrect unboxing.

如果将下列语句:

int j = (short) o;

改为:

int j = (int) o;

将得到以下输出: Unboxing OK.

最新回复(0)