编译错误 · error CS0165

使用了未赋值的局部变量"x"

你读取了一个变量,但在此之前没有任何东西被存进去。与大多数语言不同,C# 拒绝塞给你一个默不作声的零——它把你拦在编译期,因为"意外读到垃圾"正是那种运行时永远查不出来的 bug。

亲眼看它发生

int total;
Console.WriteLine(total + 1);   // total 声明了,但从没被赋值

int total; 预定了名字和存储——但没有往里放值。读它就是无意义操作,C# 直说。最简单的修法:

int total = 0;
Console.WriteLine(total + 1);

有意思的情况:赋值了,但不是"明确赋值"

CS0165 真正想教的是:变量必须在每一条能到达读取点的路径上被赋值。在 if 里赋值不算数——编译器会替"条件不成立的那个分支"做打算:

string label;
if (score > 50)
{
    label = "pass";          // 只在条件成立时赋值
}
Console.WriteLine(label);    // error CS0165: 那 score 是 30 呢?

(完整的分支分析超出浏览器引擎的简化检查——引擎只验证"读取前是否赋过值";Visual Studio 应用的是这里展示的完整"每条路径"规则。)

修法一:分支前先给个合理的默认值

void Report(int score)
{
    string label = "fail";          // 默认值覆盖所有路径
    if (score > 50)
    {
        label = "pass";
    }
    Console.WriteLine(label);
}

Report(90);
Report(30);

修法二:让编译器证明赋值了——加上 else

int x = -5;
string sign;
if (x > 0)
{
    sign = "positive";
}
else
{
    sign = "negative or zero";
}
Console.WriteLine(sign);   // OK: if+else 覆盖所有路径,编译器满意

修法三:声明时就初始化(惯用默认)

int sum = 0;                 // 累加器从 0 起步——永远如此
for (int i = 1; i <= 5; i++)
{
    sum += i;
}
Console.WriteLine("Sum after loop: " + sum);

为什么 C# 不把所有东西默认成 0?

类的字段确实有默认值(0、null、false)——因为类一定会跑构造器。局部变量没有,因为 C# 的设计者拍板:你没写过值就去读,几乎必然是 mistake。这个错误是语言在帮你——和 CS0029 同一种哲学:拒绝瞎猜,逼你说清楚。

常见问答

怎么修 C# 里的 CS0165?

局部变量在赋值前被读取时触发。累加器/计数器在声明时初始化(int sum = 0;);分支里赋值的,先给默认值或补 else 保证每条路径都赋值——单个 if 分支里的赋值不够。

为什么 C# 不把局部变量默认成 0?

类字段有默认值;局部变量没有是刻意设计——未赋值就读几乎必然是 bug,编译错误比默不作声的零好得多。

排查清单