C# 封箱和拆箱
封箱(boxing)是把值類型轉(zhuǎn)換為System.Object類型,或者轉(zhuǎn)換為由值類型實(shí)現(xiàn)的接口類型。拆箱(unboxing)是相反的轉(zhuǎn)換過(guò)程。
例如,下面的結(jié)構(gòu)類型:
struct MyStruct
{
public int Val;
}
可以把這種類型的結(jié)構(gòu)放在object類型的變量中,對(duì)其封箱:
MyStruct valTypel = new MyStruct();
valTypel.Val = 5;
object refType = valTypel?
其中創(chuàng)建了一個(gè)類型為MyStruct的新變量valTypel,并把一個(gè)值賦予這個(gè)結(jié)構(gòu)的Val成員,然后把它封箱在object類型的變量refType中。
以這種方式封箱變量而創(chuàng)建的對(duì)象,會(huì)包含值類型變量的一個(gè)副本的引用,而不包含源值類型變量的引用。要進(jìn)行驗(yàn)證,可以修改源結(jié)構(gòu)的內(nèi)容,然后把對(duì)象中包含的結(jié)構(gòu)拆箱到新變量中,并檢査其內(nèi)容:
valTypel.Val = 6;
MyStruct valType2 = (MyStruct)refType;
WriteLine {$uvalType2 .Val = {valType2 .Val}");
執(zhí)行這段代碼將得到如下輸出結(jié)果:
valType2.Val = 5
但在把一個(gè)引用類型賦予對(duì)象時(shí),將執(zhí)行不同的操作。把MyStruct改為一個(gè)類(不考慮這個(gè)類名不合適的情況),即可看到這種情形:
class MyStruct
{
public int Val;
}
如果不修改上面的客戶代碼(再次忽略名稱有誤的變量),就會(huì)得到如下輸出結(jié)果:
valType2.Val = 6
也可以把值類型封箱到接口類型中,只要它們實(shí)現(xiàn)這個(gè)接口即可。例如,假定MyStruct類型實(shí)現(xiàn)IMylnterface接口,如下所示:
interface IMylnterface {}
struct MyStruct : IMylnterface
{
public int Val;
}
接著把結(jié)構(gòu)封箱到一個(gè)IMylnterface類型中,如下所示:
MyStruct valTypel = new MyStruct ();
IMylnterface refType = valTypel;
然后使用一般的數(shù)據(jù)類型轉(zhuǎn)換語(yǔ)法對(duì)其拆箱:
MyStruct ValType2 = {MyStruct)refType;
從這些示例中可以看出,封箱是在沒(méi)有用戶干涉的情況下進(jìn)行的(即不需要編寫任何代碼),但拆箱一個(gè)值需要進(jìn)行顯式轉(zhuǎn)換,即需要進(jìn)行數(shù)據(jù)類型轉(zhuǎn)換(封箱是隱式的,所以不需要進(jìn)行數(shù)據(jù)類型轉(zhuǎn)換)。
讀者可能想知道為什么要這么做。封箱非常有用,有兩個(gè)非常重要的原因。首先,它允許在項(xiàng)的類型是object的集合(如ArrayList)中使用值類型。其次,有一個(gè)內(nèi)部機(jī)制允許在值類型(例如int和結(jié)構(gòu))上調(diào)用object方法。
最后需要注意的是,在訪問(wèn)值類型內(nèi)容前,必須進(jìn)行拆箱。
點(diǎn)擊加載更多評(píng)論>>