C# 所有型別(值型別、參考型別)皆隱含繼承自 System.Object。值型別(int、struct、enum)在需要當作物件使用時,會自動**裝箱**為堆上物件;取回值時**拆箱**。理解這機制,才能寫出高效能、無 Bug 的轉換代碼。
| 關鍵字 | 系統型別 | 大小 | 範圍/說明 |
|---|---|---|---|
| bool | System.Boolean | 1 byte | true/false |
| byte | System.Byte | 1 byte | 0~255 |
| sbyte | System.SByte | 1 byte | -128~127 |
| char | System.Char | 2 bytes | UTF-16 字元 |
| short | System.Int16 | 2 bytes | -32,768~32,767 |
| ushort | System.UInt16 | 2 bytes | 0~65,535 |
| int | System.Int32 | 4 bytes | -2.14B~2.14B |
| uint | System.UInt32 | 4 bytes | 0~4.29B |
| long | System.Int64 | 8 bytes | ±9.22×10¹⁸ |
| ulong | System.UInt64 | 8 bytes | 0~1.84×10¹⁹ |
| float | System.Single | 4 bytes | 7 位精度 |
| double | System.Double | 8 bytes | 15-16 位精度 |
| decimal | System.Decimal | 16 bytes | 28-29 位精度,貨幣首選 |
| string | System.String | 參考型別 | 不可變字串 |
驗證別名:typeof(int) == typeof(System.Int32) 為 true。
// 隱式:小 → 大,無資料遺失
byte b = 10;
short s = b; // OK
int i = s; // OK
long l = i; // OK
float f = l; // OK
double d = f; // OK
// 顯式:大 → 小,可能溢位/截斷
int x = 300;
byte y = (byte)x; // y = 44 (300 % 256)
checked { byte z = (byte)x; } // 拋 OverflowException
// 浮點 → 整數:截斷小數
double pi = 3.14159;
int ipi = (int)pi; // 3
// decimal 需顯式轉雙精度
decimal m = 1.23m;
double dm = (double)m;
最佳實踐:財務計算嚴禁 float/double,統一用 decimal;轉換前用 checked 區塊或手動檢查範圍。
char c = 'A';
int ascii = (int)c; // 65
char c2 = (char)65; // 'A'
char zh = '中';
int unicode = (int)zh; // 20013 (0x4E2D)
char zh2 = (char)20013; // '中'
// 取得字串中每字元編碼
foreach (char ch in "Hello中文")
Console.WriteLine($"'{ch}' = U+{(int)ch:X4}");
// 數值 → 字串
int n = 42;
string s1 = n.ToString(); // "42"
string s2 = n.ToString("D5"); // "00042"
string s3 = n.ToString("X"); // "2A" (十六進位大寫)
string s4 = n.ToString("X4"); // "002A"
string s5 = 3.14159.ToString("F2"); // "3.14"
string s6 = 1234.5.ToString("N"); // "1,234.50"
string s7 = 0.25.ToString("P"); // "25.00 %"
// 字串 → 數值
int a = int.Parse("42");
bool ok = int.TryParse("abc", out int b); // false, b=0
double d = double.Parse("3.14", System.Globalization.CultureInfo.InvariantCulture);
// 處理千分位、貨幣符號
int c = int.Parse("1,234", System.Globalization.NumberStyles.AllowThousands);
string str = "Hello";
// 字串 → char[]
char[] chars = str.ToCharArray();
// char[] → 字串
string s = new string(chars);
string s2 = new string(chars, 1, 3); // "ell" (索引1起長度3)
// 字串 → byte[] (指定編碼)
byte[] utf8 = Encoding.UTF8.GetBytes(str);
byte[] ascii = Encoding.ASCII.GetBytes(str);
byte[] unicode = Encoding.Unicode.GetBytes(str); // Little-Endian UTF-16
byte[] bigEndian = Encoding.BigEndianUnicode.GetBytes(str);
// byte[] → 字串
string restored = Encoding.UTF8.GetString(utf8);
string partial = Encoding.UTF8.GetString(utf8, 1, 3);
關鍵差異:Encoding.Default (ANSI 代碼頁) vs Encoding.Unicode (UTF-16LE) vs Encoding.UTF8。中文在 Default 佔 2 bytes,在 Unicode/UTF-8 佔 2/3 bytes。
using System.Buffers.Binary; // .NET Core 2.1+ / .NET 5+ 高效能
using System.BitConverter; // 傳統
int val = 0x01020304;
byte[] bytes = BitConverter.GetBytes(val); // 小端序:04 03 02 01
// 或指定端序
BinaryPrimitives.WriteInt32BigEndian(bytes, val); // 01 02 03 04
// 反向
int fromBytes = BitConverter.ToInt32(bytes, 0);
int fromBE = BinaryPrimitives.ReadInt32BigEndian(bytes);
// 結構體序列化
struct Vec3 { public float X, Y, Z; }
Vec3 v = new Vec3 { X=1, Y=2, Z=3 };
byte[] buf = new byte[12];
BinaryPrimitives.WriteSingleBigEndian(buf[0..4], v.X);
BinaryPrimitives.WriteSingleBigEndian(buf[4..8], v.Y);
BinaryPrimitives.WriteSingleBigEndian(buf[8..12], v.Z);
// 數值 → 十六進位字串
int n = 188;
string hex1 = n.ToString("X"); // "BC"
string hex2 = n.ToString("X4"); // "00BC"
string hex3 = n.ToString("x"); // "bc"
// 十六進位字串 → 數值
int m1 = int.Parse("BC", System.Globalization.NumberStyles.HexNumber);
int m2 = Convert.ToInt32("BC", 16);
int m3 = int.Parse("00BC", System.Globalization.NumberStyles.HexNumber);
// 位元組陣列 → 連續十六進位字串
byte[] data = { 0xDE, 0xAD, 0xBE, 0xEF };
string hex = BitConverter.ToString(data).Replace("-", ""); // "DEADBEEF"
string hex2 = string.Concat(data.Select(b => b.ToString("X2")));
DateTime now = DateTime.Now;
// Ticks:從 0001-01-01 00:00:00 起的 100ns 間隔數
long ticks = now.Ticks;
DateTime fromTicks = new DateTime(ticks);
// OADate:OLE Automation Date(Double),整數部=日期,小數部=時間
// 相容 VB6 / Excel / COM
double oa = now.ToOADate(); // 例:45321.65432
DateTime fromOA = DateTime.FromOADate(oa);
// Unix 時間戳(秒/毫秒)
long unixSec = ((DateTimeOffset)now).ToUnixTimeSeconds();
long unixMs = ((DateTimeOffset)now).ToUnixTimeMilliseconds();
DateTime fromUnix = DateTimeOffset.FromUnixTimeSeconds(unixSec).DateTime;
DateTime dt = new DateTime(2024, 1, 15, 14, 30, 45);
dt.ToString("yyyy-MM-dd HH:mm:ss"); // 2024-01-15 14:30:45
dt.ToString("yyyy/MM/dd"); // 2024/01/15
dt.ToString("yyyy年M月d日"); // 2024年1月15日
dt.ToString("HH:mm"); // 14:30
dt.ToString("tt hh:mm"); // 下午 02:30
dt.ToString("ddd, dd MMM yyyy HH':'mm':'ss 'GMT'", CultureInfo.InvariantCulture); // RFC1123
// 包含字面字元需用單引號跳脫
dt.ToString("'Year:' yyyy 'Month:' MM"); // Year: 2024 Month: 01
// .NET Core 2.1+ 避免分配 byte[]
int value = 12345;
Span buffer = stackalloc byte[4];
BinaryPrimitives.WriteInt32LittleEndian(buffer, value);
// 直接寫入 Socket/Stream
socket.Send(buffer);
| 轉換方向 | 核心 API | 注意事項 |
|---|---|---|
| 值型別 → 物件 | 隱式裝箱 | 配置堆記憶體,避免熱路徑頻繁裝箱 |
| 物件 → 值型別 | 拆箱 ((T)obj) | 型別必須完全匹配,否則 InvalidCastException |
| 數值 → 數值 | 隱式/顯式轉換 | 顯式轉換加 checked 防溢位 |
| 數值 → 字串 | ToString(format) | 格式字串參考標準/自訂數值格式 |
| 字串 → 數值 | Parse/TryParse | 優先用 TryParse 避免例外 |
| 字串 ↔ 位元組 | Encoding.GetBytes/GetString | 必須指定編碼,跨平台統一用 UTF-8 |
| 數值 ↔ 位元組 | BitConverter/BinaryPrimitives | 注意端序,網路傳輸用 BigEndian |
| 十六進位 ↔ 數值 | ToString("X")/Parse(..., HexNumber) | 不含 0x 前綴 |
| DateTime ↔ Ticks | .Ticks / new DateTime(ticks) | 100ns 解析度,適合資料庫儲存 |
| DateTime ↔ OADate | ToOADate/FromOADate | COM/Excel 互通 |
| DateTime ↔ Unix | ToUnixTimeSeconds/FromUnixTimeSeconds | 跨語言/系統標準 |