編譯錯誤 · error CS0029

無法將型別"X"隱式轉換為"Y"

你把一種型別的值,放進了期待另一種型別的位置——而 C# 無法(或不肯)替你悄悄轉換。按一下下面壞程式碼的執行按鈕:報出來的錯誤和真實編譯器是同一套規則。

親眼看它發生

int count = "5";   // 帶引號的是文本,不是數量

編譯器拒絕瞎猜。"5"(帶引號)是 string——兩個字元,一個 '5',跟"數量"沒有任何關係。C# 當然可以試著去解析它,但猜錯了就是執行時崩潰,所以它在編譯期就把你攔下來。

四種常見成因(和修法)

1. string → int:你其實想解析

string input = "5";
int count = int.Parse(input);   // 明確的轉換,解析失敗會拋 FormatException
Console.WriteLine(count + 1);

int.Parse 負責轉換,而且轉不動時會說實話。如果失敗是正常情況(比如使用者輸入),改用 int.TryParse(input, out int count)——返回 false 而不是拋異常。

2. 數字 → string:你其實想拼接

int apples = 3;
string msg = "You have " + apples + " apples";   // + 會自動呼叫 ToString()
Console.WriteLine(msg);

3. bool 和它的文本形式

bool ok = "true"; 報的是同一個錯。要顯式解析:

bool ok = bool.Parse("true");
Console.WriteLine(ok);

4. 型別不相關的物件

把 Dog 賦給 Car 變數,是同一個錯誤的類形式——根本不存在轉換:

class Dog { public string Name; }
class Car { public string Model; }

Dog d = new Dog { Name = "Rex" };
Car c = d;   // CS0029: 無法將型別"Dog"隱式轉換為"Car"

近親:CS0266(那個"差一個強制轉換"的兄弟)

如果兩種型別可以轉換、但只能顯式轉——最典型的就是 double → int,會丟小數——你看到的會是 CS0266,提示語是"存在顯式轉換(是否缺少強制轉換?)":

double price = 9.99;
int rounded = price;        // CS0266: 會悄悄丟掉 .99
double price = 9.99;
int rounded = (int)price;   // 顯式轉換:"我知道,截斷它"
Console.WriteLine(rounded);

經驗法則:CS0029 = 不存在隱式轉換(去解析、去拼接、或者重新想型別);CS0266 = 轉換存在但必須自己寫出來,接受那份損失。

常見問答

CS0029 在 C# 裡是什麼意思?

CS0029 表示你把一種型別的值賦給了不存在隱式轉換的另一種型別的位置——比如 int count = "5";。修法:字串用 int.Parse(s) 解析;反向用 .ToString() 或 $"…" 插值拼文本;double 轉 int 用顯式 (int) 強轉(那種情況報的是 CS0266)。

CS0029 和 CS0266 有什麼區別?

CS0029 表示隱式轉換根本不存在(string 轉 int)——必須主動解析或轉換。CS0266 表示轉換存在但會丟資料(double 轉 int),所以編譯器要求你寫出顯式強轉,例如 (int)price。

排查清單