所謂「裝箱/拆箱」在 C# 中實際上是**值型別與其對應參考型別包裝類別之間的轉換**。C# 為了語法簡潔,提供了關鍵字作為**型別別名** (alias),編譯時會對應至 .NET 運行時的實際類別。
| C# 關鍵字 | .NET 類別 | 分類 | 大小/範圍 |
|---|---|---|---|
| bool | System.Boolean | 值型別 | 1 byte (true/false) |
| byte | System.Byte | 值型別 | 0~255 |
| sbyte | System.SByte | 值型別 | -128~127 |
| char | System.Char | 值型別 | UTF-16 字元 |
| short | System.Int16 | 值型別 | -32,768~32,767 |
| ushort | System.UInt16 | 值型別 | 0~65,535 |
| int | System.Int32 | 值型別 | -2,147,483,648~2,147,483,647 |
| uint | System.UInt32 | 值型別 | 0~4,294,967,295 |
| long | System.Int64 | 值型別 | ±9.22×10¹⁸ |
| ulong | System.UInt64 | 值型別 | 0~1.84×10¹⁹ |
| float | System.Single | 值型別 | 7 位有效數字 |
| double | System.Double | 值型別 | 15-16 位有效數字 |
| decimal | System.Decimal | 值型別 | 28-29 位有效數字 |
| object | System.Object | 參考型別 | 所有型別基類 |
| string | System.String | 參考型別 | 不可變字串 |
private void ShowAliases()
{
byte b = 1; char c = 'a'; short s = 1;
int i = 2; long l = 3; uint u = 4; bool bl = true;
var sb = new StringBuilder();
sb.AppendLine($"byte -> {b.GetType().FullName}"); // System.Byte
sb.AppendLine($"char -> {c.GetType().FullName}"); // System.Char
sb.AppendLine($"short -> {s.GetType().FullName}"); // System.Int16
sb.AppendLine($"int -> {i.GetType().FullName}"); // System.Int32
sb.AppendLine($"long -> {l.GetType().FullName}"); // System.Int64
sb.AppendLine($"uint -> {u.GetType().FullName}"); // System.UInt32
sb.AppendLine($"bool -> {bl.GetType().FullName}"); // System.Boolean
textBox.Text = sb.ToString();
}
int val = 123;
object obj = val; // 裝箱:配置物件、複製值
int val2 = (int)obj; // 拆箱:型別檢查、複製值
// 隱性裝箱常見場景
ArrayList list = new ArrayList();
list.Add(100); // 裝箱
int x = (int)list[0]; // 拆箱
// 避免裝箱:使用泛型集合
List genericList = new List();
genericList.Add(100); // 無裝箱
int y = genericList[0]; // 無拆箱
List<T>, Dictionary<TKey,TValue>, Span<T>) 替代 ArrayList/Hashtable/object 參數。IEquatable<T>、IComparable<T> 避免介面呼叫裝箱。理解「關鍵字 = 別名 = 系統類別」,即可明白裝箱拆箱本質為**值型別與其包裝類別 (System.Int32 等) 與 object 之間的轉換**。現代 C# 開發**以泛型為主,極少直接面對裝箱拆箱**,但理解其機制有助於效能調優與舊代碼維護。