编译错误 · 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。

排查清单