CodeGym /課程 /C# SELF /明確與隱式型別轉換

明確與隱式型別轉換

C# SELF
等級 6 , 課堂 5
開放

1. 前言

你有沒有試過把一顆西瓜塞進瓶子裡?這就像 C# 每次你叫它把一種型別的變數指定給另一種型別時遇到的狀況。有時很簡單(小數字變大數字——像把蘋果放進行李箱),有時就要小心(西瓜進瓶子——這就沒那麼容易了)。

型別轉換 就是把一個資料型別的值轉成另一個型別的操作。這很常見,像你想要加總或比較不同型別的值,或是要傳給只接受特定型別的函式時都會用到。

在現實生活中,工程師們一直都會遇到這種情況:你在付款、計算折扣、做物理運算,或是像從鍵盤輸入時解析數字(那邊全部都會是字串)。

2. 隱式型別轉換 (Implicit Conversion)

這是什麼?

隱式型別轉換就是 C# 自己幫你決定,哪些資料可以「無痛」地從一種型別轉到另一種型別。全部都自動完成——你什麼都不用寫,只要直接用值就好。

  • 編譯器不會抱怨。
  • 不需要特別的指令或 cast。
  • 不會有資料遺失(幾乎都不會啦)。

隱式型別轉換範例

int a = 42;
double b = a; // 隱式型別轉換 int -> double

Console.WriteLine(b); // 42 (但這已經是 42.0)

這裡 aint 型別自動變成 double,指定給變數 b。資料沒有遺失,因為所有 int 的值都可以放進 double

這裡 aint 型別自動變成 double,指定給變數 b。資料沒有遺失,因為所有 int 的值都可以放進 double

什麼時候會這樣?

  • 當目標型別 比來源型別寬——支援更大的資料範圍
  • 不會有資料遺失。
  • 範例:
    • intlong
    • intfloat / double
    • floatdouble
    • charint

再一個範例:

byte x = 100;
int y = x; // byte -> int (所有 byte 的值都在 int 的範圍內)

數值型別的隱式轉換表

From To
byte
short, ushort, int, uint, long, ulong, float, double, decimal
int
long, float, double, decimal
float
double
char
ushort, int, uint, long, ulong, float, double, decimal

3. 明確型別轉換 (Explicit Conversion, Type Cast)

魔法不夠用的時候?

有時候編譯器沒辦法保證轉換是安全的,就會要求你自己負責——明確告訴它你知道風險。

  • 有可能會遺失資料。
  • 值的格式可能會變。
  • 有時候根本不能轉換——會出錯。

明確型別轉換怎麼寫?

用括號語法(cast):

double pi = 3.1415;
int wholePi = (int)pi; // 明確型別轉換 double -> int

Console.WriteLine(wholePi); // 3 (小數部分被砍掉了!)

什麼時候用?

  • 當目標型別 比來源型別窄——目標型別的值範圍比來源型別小
  • 可能會遺失小數、資料、溢位。
  • 範例:
    • doubleint
    • longint
    • intbyte
    • 幾乎所有不相容型別之間的轉換。

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. 字串轉換怎麼辦:ParseConvert

型別轉換沒辦法直接在數字和字串之間用!這時要用特別的方法,例如:

string strNumber = "123";
int num = int.Parse(strNumber); // 或 Convert.ToInt32(strNumber);

但反過來(intstring)在字串串接時會自動發生:

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 6482 147 483 647,但 byte 只能放 0–255
  • 四捨五入。 一般的轉型((int)x)會直接砍掉小數。要正確四捨五入請用 Math.RoundMath.FloorMath.Ceiling
  • 數值常數。 注意 3 / 2 會得到 1(整數除法),但 3.0 / 2 就是 1.5double)!
  • 混合型別運算。 如果運算式裡有 intdouble 混在一起,結果會是 double 型別。
1
問卷/小測驗
浮點數,等級 6,課堂 5
未開放
浮點數
精確度問題與特殊值
留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION