1. 前言
你有沒有試過把一顆西瓜塞進瓶子裡?這就像 C# 每次你叫它把一種型別的變數指定給另一種型別時遇到的狀況。有時很簡單(小數字變大數字——像把蘋果放進行李箱),有時就要小心(西瓜進瓶子——這就沒那麼容易了)。
型別轉換 就是把一個資料型別的值轉成另一個型別的操作。這很常見,像你想要加總或比較不同型別的值,或是要傳給只接受特定型別的函式時都會用到。
在現實生活中,工程師們一直都會遇到這種情況:你在付款、計算折扣、做物理運算,或是像從鍵盤輸入時解析數字(那邊全部都會是字串)。
2. 隱式型別轉換 (Implicit Conversion)
這是什麼?
隱式型別轉換就是 C# 自己幫你決定,哪些資料可以「無痛」地從一種型別轉到另一種型別。全部都自動完成——你什麼都不用寫,只要直接用值就好。
- 編譯器不會抱怨。
- 不需要特別的指令或 cast。
- 不會有資料遺失(幾乎都不會啦)。
隱式型別轉換範例
int a = 42;
double b = a; // 隱式型別轉換 int -> double
Console.WriteLine(b); // 42 (但這已經是 42.0)
這裡 a 從 int 型別自動變成 double,指定給變數 b。資料沒有遺失,因為所有 int 的值都可以放進 double。
這裡 a 從 int 型別自動變成 double,指定給變數 b。資料沒有遺失,因為所有 int 的值都可以放進 double。
什麼時候會這樣?
- 當目標型別 比來源型別寬——支援更大的資料範圍。
- 不會有資料遺失。
- 範例:
- int → long
- int → float / double
- float → double
- char → int
再一個範例:
byte x = 100;
int y = x; // byte -> int (所有 byte 的值都在 int 的範圍內)
數值型別的隱式轉換表
| From | To |
|---|---|
|
|
|
|
|
|
|
|
3. 明確型別轉換 (Explicit Conversion, Type Cast)
魔法不夠用的時候?
有時候編譯器沒辦法保證轉換是安全的,就會要求你自己負責——明確告訴它你知道風險。
- 有可能會遺失資料。
- 值的格式可能會變。
- 有時候根本不能轉換——會出錯。
明確型別轉換怎麼寫?
用括號語法(cast):
double pi = 3.1415;
int wholePi = (int)pi; // 明確型別轉換 double -> int
Console.WriteLine(wholePi); // 3 (小數部分被砍掉了!)
什麼時候用?
- 當目標型別 比來源型別窄——目標型別的值範圍比來源型別小。
- 可能會遺失小數、資料、溢位。
- 範例:
- double → int
- long → int
- int → byte
- 幾乎所有不相容型別之間的轉換。
4. 來看範例
1) 會不會遺失資料?來試試看!
隱式型別轉換——沒問題!
int small = 25;
long big = small; // 隱式型別轉換 (int -> long)
Console.WriteLine(big); // 25
明確型別轉換——危險區!
int big = 1000;
byte small = (byte)big; // 明確型別轉換 (int -> byte)
Console.WriteLine(small); // 232 (!) 因為 1000 放不進 byte (0..255)
這裡的結果是「神奇」的 232,因為 1000 % 256 == 232。
2) 處理浮點數 (double, float)
double number = 9.99;
int approximate = (int)number; // 小數部分直接砍掉
Console.WriteLine(approximate); // 9
3) 整數和浮點數之間的轉換 (double ↔ int)
int apples = 5;
double exactApples = apples; // int -> double (隱式)
Console.WriteLine(exactApples); // 5.0
double bananaWeight = 2.77;
int weightForReport = (int)bananaWeight; // double -> int (明確)
Console.WriteLine(weightForReport); // 2
5. 字串轉換怎麼辦:Parse 和 Convert
型別轉換沒辦法直接在數字和字串之間用!這時要用特別的方法,例如:
string strNumber = "123";
int num = int.Parse(strNumber); // 或 Convert.ToInt32(strNumber);
但反過來(int → string)在字串串接時會自動發生:
int number = 42;
string message = "答案: " + number; // 隱式轉換 int → string
6. 型別轉換的錯誤
歷史小故事:有一次有人忘了明確轉型,結果最後付款金額比應該的少了 250 倍... 學生們要小心啊!
很常見的錯誤:試圖隱式轉換型別,但有可能會遺失資料。
int big = 500;
byte small = big; // 編譯器:「不行!可能會遺失資料!」
這裡就需要明確型別轉換:
byte small = (byte)big; // 但你有可能會遺失資料!
另一個常見 bug——忘了考慮小數部分:
double x = 2.9;
int y = (int)x; // y == 2,小數部分不見了
要照數學規則四捨五入,請用 Math.Round:
int y = (int)Math.Round(x); // y == 3
7. 轉型陷阱
- 資料遺失。 一定要檢查值有沒有超出型別的範圍。例如 int 可以放 -2 147 483 648 到 2 147 483 647,但 byte 只能放 0–255。
- 四捨五入。 一般的轉型((int)x)會直接砍掉小數。要正確四捨五入請用 Math.Round、Math.Floor、Math.Ceiling。
- 數值常數。 注意 3 / 2 會得到 1(整數除法),但 3.0 / 2 就是 1.5(double)!
- 混合型別運算。 如果運算式裡有 int 跟 double 混在一起,結果會是 double 型別。
GO TO FULL VERSION