實值型別實例僅含數值;參考型別實例含物件標頭 (虛方法表、中繼資料等),記憶體開銷大。編譯器有時可優化,但不保證。追求效率時使用實值型別有益。
裝箱橋接數值與物件。CLR 所有型別直接/間接繼承 Object,但數值不是。將堆疊數值視為物件需調用 Object 方法,CLR 提供裝箱:ldloc 入棧 → box 指令配置物件 (含標頭) → stloc 存儲參考。
object o = 123; (視為向上轉型)。__box 關鍵字 Object* o = __box(i);,保留靜態型別資訊 int __gc* o = __box(i);,拆箱簡單 int c = *o;。Managed C++ 語法負擔大,C++/CLI 採隱含裝箱並保持型別安全:
int i = 123;
int^ hi = i; // 隱含裝箱,型別為 int^
int c = *hi; // 拆箱
hi = nullptr; // 空控制代碼,不可用 0 (會裝箱整數 0)
nullptr 為新保留字,等同 C# null,已提議納入標準 C++。
| 種類 | C# | Managed C++ | C++/CLI |
|---|---|---|---|
| 參考型別 | class | __gc class | ref class / ref struct |
| 實值型別 | struct | __value class | value class / value struct |
C++/CLI 使用「空隙關鍵字」(非保留字),ref/value 可作變數名。CLR 僅支援公有繼承,private/protected 繼承編譯錯誤。
裝箱物件記住原始型別:
int z = 44; float f = 33.567;
Object^ o1 = z; Object^ o2 = f;
Console::WriteLine(o1->GetType()); // System.Int32
Console::WriteLine(o2->GetType()); // System.Single
拆箱型別不符拋出 InvalidCastException:
int y = *reinterpret_cast<int^>(o2); // 錯誤
float g = *reinterpret_cast<float^>(o1); // 錯誤
IL 層面 box 指令建立新物件並複製資料,確保型別安全。