在 C# 開發中,將字串或浮點數轉為 int 是高頻操作。主要有三種途徑:強制轉型、Convert.ToInt32、int.Parse/TryParse。它們在處理小數、非數字字串、null 時行為截然不同,選錯會導致例外或邏輯錯誤。本文逐一實測並總結適用場景。
| 方法 | 語法 | 小數處理 | 非數字字串 | null 輸入 | 效能 |
|---|---|---|---|---|---|
| 強制轉型 | (int)doubleVal | **截斷**(向零取整) | 編譯錯誤(僅限數值型別) | N/A | 最快(IL 直接指令) |
| Convert.ToInt32 | Convert.ToInt32(val) | **四捨五入**(銀行家算法) | 拋 FormatException | 回傳 0 | 中等(內部呼叫 Parse) |
| int.Parse | int.Parse(str) | **拋例外**(只接受整數字串) | 拋 FormatException | 拋 ArgumentNullException | 中等 |
| int.TryParse | int.TryParse(str, out int) | **失敗回 false**(不修改 out) | 回 false,out=0 | 回 false,out=0 | 最佳(無例外開銷) |
// 1. 浮點數轉換
double d = 2.8;
int a = (int)d; // 2 (截斷)
int b = Convert.ToInt32(d); // 3 (四捨五入)
// 2. 字串 "2.8"
int c1 = int.Parse("2.8"); // FormatException
int c2 = Convert.ToInt32("2.8");// FormatException
int c3;
bool ok = int.TryParse("2.8", out c3); // false, c3=0
// 3. 字串 "2"
int d1 = int.Parse("2"); // 2
int d2 = Convert.ToInt32("2"); // 2
int d3;
int.TryParse("2", out d3); // true, d3=2
// 4. 字元 'a' (ASCII 97)
char ch = 'a';
int e1 = (int)ch; // 97
int e2 = Convert.ToInt32("a"); // FormatException
int e3 = int.Parse("a"); // FormatException
int e4;
int.TryParse("a", out e4); // false, e4=0
// 5. null 字串
string s = null;
int f1 = Convert.ToInt32(s); // 0
// int.Parse(s) -> ArgumentNullException
int f2;
int.TryParse(s, out f2); // false, f2=0
(int)2.8 → 2、(int)-2.8 → -2(向零截斷)。Convert.ToInt32(2.8) → 3、Convert.ToInt32(2.5) → 2(銀行家算法:.5 向最近偶數)。Math.Floor/Math.Ceiling 或 decimal 運算。int.Parse 適合「確定合法」的情境(如內部設定檔),否則 **務必改用 TryParse** 避免例外拋捕捉效能損失與程式中斷。
null 容忍度只有 Convert.ToInt32(null) 回傳 0 不拋例外,適合「空值視為 0」的業務邏輯;但若需區分「空值」與「0」,請用 TryParse 搭配 string.IsNullOrEmpty 先檢查。
(int)'a' 取得 Unicode 碼位(97),這是**字元轉數值**,非字串解析。切勿混淆。
int.TryParse(input, out var val),檢查回傳 bool 再決定流程。int.Parse(str) 程式碼最簡潔。(int)Math.Round(d, MidpointRounding.AwayFromZero) 明確指定捨入模式,避免銀行家算法驚喜。DBNull.Value 處理:Convert.ToInt32(row["col"]) 可直接轉 DBNull 為 0。TryParse 無例外開銷,優於 Parse + try-catch。三大方法各有設計初衷:強制轉型給數值型別截斷;Convert 給通用物件轉換(含 null 容忍與四捨五入);Parse/TryParse 專司字串解析,**預設首選 TryParse** 以兼顧安全與效能。理解差異,才能寫出健壯的 C# 程式碼。