《c#高階程式設計》第6版154頁。
基類和派生類之間的資料型別轉換
myderived直接或間接派生於mybase,從myderived到mybase的轉換:
myderived derivedobject = new myderived();
mybase basecopy = derivedobject;
myderived隱式轉換為mybase,因為對類mybase的任何引用都可以引用類mybase的物件或派生於mybase的物件。在oo程式設計中,派生類的例項實際上是基類的例項,但加上了一些額外的資訊。在基類上定義的所有函式和字段也都在派生類上定義了。
下面看看另一種方式:
mybase derivedobject = new myderived();
mybase baseobject = new mybase();
myderived derivedcopy1 = (myderived) derivedobject; // ok
myderived derivedcopy2 = (myderived) baseobject; // throws exception
最後乙個語句在執行時會丟擲乙個異常。在進行資料型別轉換時,會檢查被引用的物件。因為基類引用實際上可以引用乙個派生類例項,所以這個物件可能是要轉換的派生類的乙個例項。如果是這樣,轉換就會成功,派生的引用被設定為引用這個物件。但如果該物件不是派生類(或者派生於這個類的其他類)的乙個例項,轉換就會失敗,丟擲乙個異常。
注意,編譯器已經提供了基類和派生類之間的轉換,這種轉換實際上並沒有對物件進行任何資料轉換。如果要進行的轉換是合法的,它們也僅是把新引用設定為對物件的引用。這些轉換在本質上與使用者定義的轉換不同。例如,在前面的******currency示例中(150頁),我們定義了currency結構和float之間的轉換。在float到currency的轉換中,則例項化了乙個新currency結構,並用要求的值進行初始化。如果要把mybase例項轉換為myderived物件,其值根據mybase例項的內容來確定,就不能使用資料型別轉換語法。最合適的選項通常是定義乙個派生類的建構函式,它的引數是乙個基類例項,讓這個建構函式執行相關的初始化:
class derivedclass : baseclass
// etc.
裝箱和拆箱資料型別轉換
從結構(或基本型別)到object的轉換總是一種隱式轉換,因為這種轉換是從派生型別到基本型別的轉換。例如,currency結構:
currency balance = new currency(40, 0);
object basecopy = balance;
在執行上述隱式轉換時,balance的內容被複製到堆上,放在乙個裝箱的物件上,basecopy物件引用設定為該物件。在後台發生的情況是:在最初定義currency結構時,.net framework隱式地提供另乙個(隱式)類,即裝箱的currency類,它包含與currency結構相同的所有字段,但卻是乙個引用型別,儲存在堆上。無論這個值型別是乙個結構,還是乙個列舉,定義它時都存在類似的裝箱引用型別,對應於所有的基本值型別,如int、double和uint。不能也不必在源**中直接程式設計訪問這些裝箱型別,但在把乙個值型別轉換為object時,它們是在後台工作的物件。在隱式地把currency轉換為object時,會例項化乙個裝箱的currency例項,並用currency結構中的所有資料進行初始化。在上面的**中,basecopy物件引用的就是這個已裝箱的currency例項。通過這種方式,就可以實現從派生類到基類的轉換,並且,值型別的語法與引用型別的語法一樣。
轉換的另乙個方式稱為拆箱。與在基本引用型別和派生引用型別之間的轉換一樣,這是一種顯式轉換,因為如果要轉換的物件不是正確的型別,會丟擲乙個異常:
object derivedobject = new currency(40, 0);
object baseobject = new object();
currency derivedcopy1 = (currency)derivedobject; // ok
currency derivedcopy2 = (currency)baseobject; // exception thrown
上述**的工作方式與前面的引用型別一樣。把derivedobject轉換為currency成功進行,因為derivedobject實際上引用的是裝箱currency例項——轉換的過程是把已裝箱的currency物件的字段複製到乙個新的currency結構中。第二個轉換會失敗,因為baseobject沒有引用已裝箱的currency物件。
在使用裝箱和拆箱時,這兩個過程都把資料複製到新裝箱和拆箱的物件上,理解這一點是非常重要的。這樣,對裝箱物件的操作就不會影響原來值型別的內容。
裝箱 拆箱 基本資料型別轉換
基本資料型別不是物件,也就是使用int double boolean等定義的變數 常量。基本型別沒有可呼叫的方法 int i 1 integer i 1 裝箱 相當於編譯器自動為您作以下的語法編譯 integer i integer.valueof 1 integer i 10 裝箱 intt i ...
資料型別及自動裝箱拆箱
資料型別 物件型別 基本資料型別 基本型別 整形 byte short int long 浮點型 float double 字元型 char 布林型別 boolean 物件型別 string 包裝類 byte,short,integer,long,float,double,char,boolean,...
型別的裝箱和拆箱
c 使用單類層次的單一繼承 所有類都繼承自object基類,而且不可能多重繼承。但是c 的介面提供了許多多重繼承的功能 型別的裝箱和拆箱 boxing and unboxing types 裝箱 boxing 和拆箱 unboxing 是使值型別 如整數 能夠被當成引用型別 物件 的處理過程。值被 ...