身為 C# 開發者,我們每天都在使用 int、string、bool 等類型,但真正理解它們背後機制的人卻不多。雖然不懂基元類型不影響日常開發,但在面試、效能優化、與底層互操作等場景中,這份知識卻能讓你脫穎而出。本文將透過實際 IL 代碼驗證,深入剖析 C# 基元類型與 .NET Framework Class Library (FCL) 的映射關係,並解開 int vs Int32、string vs String 等經典疑問。
先看一段常見的程式碼片段:
// 最簡單
int a = 0;
// 較簡潔
Int32 b = 0;
// 不簡潔
int c = new int();
// 最不簡潔
System.Int32 d = new System.Int32();
編譯後查看 IL 代碼(使用 ILDasm 或 dotnet-ildasm):
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
.maxstack 1
.locals init ([0] int32 a,
[1] int32 b,
[2] int32 c,
[3] int32 d)
IL_0000: nop
IL_0001: ldc.i4.0
IL_0002: stloc.0
IL_0003: ldc.i4.0
IL_0004: stloc.1
IL_0005: ldc.i4.0
IL_0006: stloc.2
IL_0007: ldc.i4.0
IL_0008: stloc.3
IL_0009: ret
}
結論:四種寫法編譯後全都變成 int32,且皆以 ldc.i4.0 初始化為 0。原因在於 C# 編譯器將基元類型視為 FCL 類型的別名。
| C# 關鍵字 | FCL 完整類型名稱 | CLS-Compliant |
|---|---|---|
| sbyte | System.SByte | No |
| byte | System.Byte | Yes |
| short | System.Int16 | Yes |
| ushort | System.UInt16 | No |
| int | System.Int32 | Yes |
| uint | System.UInt32 | No |
| long | System.Int64 | Yes |
| ulong | System.UInt64 | No |
| char | System.Char | Yes |
| float | System.Single | Yes |
| double | System.Double | Yes |
| decimal | System.Decimal | Yes |
| object | System.Object | Yes |
| string | System.String | Yes |
| bool | System.Boolean | Yes |
表格揭示兩個關鍵事實:
int 編譯時直接對應 System.Int32,兩者在 IL 層面完全等價。using 別名理解映射關係若把基元類型視為編譯器內建的 using 別名,即可直觀理解:
using int = System.Int32;
using string = System.String;
using byte = System.Byte;
// ...其他基元類型同理
conv.i8觀察以下代碼:
Int32 i = 0;
Int64 j = i; // 隱式轉換
對應 IL:
IL_0003: ldloc.0 // 載入 i
IL_0004: conv.i8 // 轉換為 int64
IL_0005: stloc.1 // 存入 j
物件導向視角的疑問:Int32 與 Int64 皆為 struct,無繼承關係,為何能隱式轉換?
答案:這是 CLR 針對基元類型內建的特殊規則。CLR 定義了基元類型之間的隱式/顯式轉換邏輯,並直接在 IL 指令集中提供 conv.* 系列操作碼,繞過一般物件的型別轉換規則。
int → long、float → double),直接賦值即可。long → int、double → float),需加括號強制轉型:int x = (int)bigNumber;。int、string),可讀性較佳,團隊協作一致性高。System.Int32),避免語言差異導致誤解。new int(),預設建構函式僅增加語法雜訊,int x = 0; 即可。基元類型是 C# 與 CLR 類型系統的橋樑。理解其與 FCL 的映射、IL 表現、轉換規則,不僅能應對面試,更能在效能敏感、互操作場景中寫出更精準、可維護的代碼。下次再看到 int vs Int32 的爭論,你已經知道答案:它們在編譯後根本就是同一個東西。