C# 作為強型別語言,類型轉換貫穿開發始終。從基本的數值轉換、字串解析,到進階的位元操作、日期序列化,理解背後機制能避免效能損耗、資料溢位與編碼錯誤。本文將官方文件與實戰經驗結合,整理出 10 大類型轉換場景的標準作法與陷阱提醒。
C# 關鍵字 (如 int) 實為對應 System 命名空間結構體的別名。編譯器會自動處理裝箱 (值型別 → object) 與拆箱 (object → 值型別),開發者無需手動干預,但必須熟記對應關係:
| C# 關鍵字 | 系統類型 | 說明 |
|---|---|---|
bool | System.Boolean | 布林值 |
byte | System.Byte | 無號 8 位元 (0~255) |
sbyte | System.SByte | 有號 8 位元 (-128~127) |
char | System.Char | Unicode 字元 (16 位元) |
short | System.Int16 | 有號 16 位元 |
ushort | System.UInt16 | 無號 16 位元 |
int | System.Int32 | 有號 32 位元 |
uint | System.UInt32 | 無號 32 位元 |
long | System.Int64 | 有號 64 位元 |
ulong | System.UInt64 | 無號 64 位元 |
float | System.Single | 單精度浮點數 |
double | System.Double | 雙精度浮點數 |
decimal | System.Decimal | 高精度十進位 (財務計算首選) |
驗證技巧: 使用 variable.GetType().FullName 即可在執行期確認實際類型。
依位元寬度由小到大:byte → short → int → long → float → double。編譯器自動處理。
byte a = 1;
short b = a; // OK
int c = b; // OK
long d = c; // OK
float e = d; // OK
double f = e; // OK
反方向或有號/無號互轉需強制轉型 (TargetType)value。
int g = 265;
byte h = (byte)g; // 結果為 9 (265 % 256),高位元被截斷!
⚠ 陷阱: 強制轉型不會拋出例外 (除非在checked區塊),資料靜默截斷極難除錯。建議關鍵路徑使用checked或Convert.ToByte()(會拋出OverflowException)。
C# char 為 UTF-16 字元,直接強制轉型即可取得代碼值:
char ch = 'A';
int ascii = (int)ch; // 65
char ch2 = (char)65; // 'A'
char cn = '中';
int unicode = (int)cn; // 20013 (0x4E2D)
char cn2 = (char)20013; // '中'
VB 程式設計師常尋找的 Asc()/Chr() 對應即為此強制轉型。
int i = 123;
string s = i.ToString(); // "123"
string s2 = i.ToString("D5"); // "00123" (格式化)
string s3 = i.ToString("X"); // "7B" (十六進位大寫)
string numStr = "456.78";
double d = double.Parse(numStr); // 標準解析
double d2 = double.Parse(numStr, NumberStyles.Float, CultureInfo.InvariantCulture); // 指定文化特性
bool success = double.TryParse(numStr, out double result); // 安全模式,推薦使用
最佳實務: 永遠優先使用TryParse避免例外開銷;跨文化特性解析時明確傳入CultureInfo.InvariantCulture。
string str = "Hello";
char[] chars = str.ToCharArray(); // ['H','e','l','l','o']
// 反向
char[] arr = { 'W', 'o', 'r', 'l', 'd' };
string str2 = new string(arr); // "World"
string str3 = new string(arr, 1, 3); // "orl" (指定起始索引與長度)
// 單字元存取:無需轉陣列
char third = str[2]; // 'l'
必須透過 System.Text.Encoding 指定編碼方式:
string s = "C#語言";
// 系統預設 ANSI (繁中為 Big5)
byte[] b1 = Encoding.Default.GetBytes(s); // 長度 6: C # 語 言
// UTF-16 Little Endian
byte[] b2 = Encoding.Unicode.GetBytes(s); // 長度 8: 每字元 2 位元組
// UTF-8 (跨平台首選)
byte[] b3 = Encoding.UTF8.GetBytes(s); // 長度 8: ASCII 1 字節,中文 3 字節
// 還原
string restored = Encoding.UTF8.GetString(b3);
關鍵差異:Encoding.Default視字元寬度輸出 1 或 2 位元組;Encoding.Unicode固定 2 位元組;Encoding.UTF8為變長編碼 (1~4 位元組)。序列化/網路傳輸強制指定 UTF-8 以確保跨平台一致性。
int val = 0x01020304;
byte[] bytes = BitConverter.GetBytes(val); // 位元組順序視 CPU 端序而定 (Little-Endian: 04 03 02 01)
// 還原
int restored = BitConverter.ToInt32(bytes, 0);
// 其他常用
BitConverter.GetBytes((short)123);
BitConverter.GetBytes(123.45);
BitConverter.GetBytes(true);
BitConverter.ToInt16(bytes, 0);
BitConverter.ToDouble(bytes, 0);
注意:BitConverter依賴執行平台端序。跨平台序列化請改用BinaryPrimitives(.NET Core 2.1+) 或手動控制位元組順序。
int num = 188;
string hexLower = num.ToString("x"); // "bc"
string hexUpper = num.ToString("X"); // "BC"
string hexPad4 = num.ToString("X4"); // "00BC" (補零至 4 位)
// 解析十六進位字串
int parsed = int.Parse("BC", NumberStyles.HexNumber); // 188
int parsed2 = int.Parse("00BC", NumberStyles.HexNumber); // 188
long ticks = DateTime.Now.Ticks; // 取得
DateTime dt = new DateTime(ticks); // 還原
double oa = DateTime.Now.ToOADate(); // 轉為 Double
DateTime dt2 = DateTime.FromOADate(oa); // 還原
// 與 VB6 / Excel / COM 互通專用
| 格式字串 | 意義 | 範例輸出 |
|---|---|---|
yyyy-MM-dd HH:mm:ss | 標準完整日期時間 | 2024-12-25 14:30:05 |
yyyy/MM/dd | 日期斜線分隔 | 2024/12/25 |
HH:mm | 24 小時制時分 | 14:30 |
hh:mm tt | 12 小時制含 AM/PM | 02:30 PM |
yyyy年M月d日 | 中文式日期 | 2024年12月25日 |
ddd | 星期縮寫 | Wed |
dddd | 星期全名 | Wednesday |
格式字串中若需輸出字面字元 (如 "year:"),用單引號包裹:
string fmt = "'year:' yyyy 'month:' MM 'day:' dd";
// 輸出: year: 2024 month: 12 day: 25
TryParse 進行字串解析,避免例外流控制。yyyy-MM-ddTHH:mm:ss.fffZ)。decimal 而非 float/double。Span<byte> + BinaryPrimitives 避免陣列配置。