Compiler error · error CS0165
Use of unassigned local variable 'x'
You read a variable before anything was stored in it. Unlike most languages, C# refuses to hand you a silent zero — it stops you at compile time, because reading garbage by accident is exactly the kind of bug you'd never find at runtime.
See it happen
int total;
Console.WriteLine(total + 1); // total was declared but never given a value
int total; reserves the name and the storage — it does not put a value there. Reading it is nonsense, and C# says so. The trivial fix:
int total = 0;
Console.WriteLine(total + 1);
The interesting case: assignment that isn't "definite"
The real lesson of CS0165 is that C# requires the variable to be assigned on every path that can reach your read. Assigning inside an if doesn't count — the compiler plans for the branch that doesn't run:
string label;
if (score > 50)
{
label = "pass"; // only assigned when the condition holds
}
Console.WriteLine(label); // error CS0165: what if score was 30?
(Full branch analysis is beyond the browser engine's simple check — it validates "was it ever assigned before the read"; Visual Studio applies the complete every-path rule shown here.)
Fix 1: assign a sensible default before the branch
void Report(int score)
{
string label = "fail"; // default covers every path
if (score > 50)
{
label = "pass";
}
Console.WriteLine(label);
}
Report(90);
Report(30);
Fix 2: make the compiler prove assignment — else
int x = -5;
string sign;
if (x > 0)
{
sign = "positive";
}
else
{
sign = "negative or zero";
}
Console.WriteLine(sign); // OK: if+else covers all paths, compiler is satisfied
Fix 3: initialize at the declaration (the idiomatic default)
int sum = 0; // accumulators start at 0 — always
for (int i = 1; i <= 5; i++)
{
sum += i;
}
Console.WriteLine("Sum after loop: " + sum);
Frequently asked
How do I fix error CS0165 in C#?
Class fields do get defaults; locals don't, by design. Reading a never-assigned local is almost always a mistake, so C# makes it a compile error instead of a silent zero — the same refuse-to-guess philosophy as CS0029.
Why doesn't C# just default local variables to 0?
undefined
Why doesn't C# just default everything to 0?
Fields of a class DO get default values (0, null, false) — because a class always runs its constructor. Locals don't, because C#'s designers decided: if you never wrote a value, reading it is almost certainly a mistake. The error is the language doing you a favor — the same philosophy as CS0029: refuse to guess, force you to say what you mean.
Checklist
- Accumulator/counter → initialize at declaration (
int sum = 0;). - Value computed in branches → either give it a default first, or add
elseso all paths assign. - Declared it to fill in later? Fine — just don't read it before the assignment; move the read below.
outparameters are "assigned by the callee" —int.TryParse(s, out int n)is legal even though you never setn.