Variables and Declarations
By the end of this lesson
Declare variables with explicit types and with var, and know when each reads better.
A variable is a name attached to a value. You met that idea in Programming Fundamentals. What C# adds is that every variable also has a type, and that type is settled the moment you declare it.
The type is decided while your code is compiled, not while it runs. Once a variable is an int, it holds whole numbers for the rest of its life. Put text in it and the build fails, before the program has run a single line.
int employeeCount = 12;
string departmentName = "Payroll";
decimal monthlyBudget = 48250.75m;
bool budgetApproved = true;
Console.WriteLine($"{departmentName} has {employeeCount} staff.");
Console.WriteLine($"Budget {monthlyBudget}, approved: {budgetApproved}");- Every declaration has the same three parts: the type, the name, then = and a starting value.
- The m on 48250.75m marks the number as a decimal. Without it C# reads the literal as a double, which is the wrong type for money.
- The $ in front of a string lets you drop {name} into the text and have the value substituted.
Two ways to write the same declaration
The keyword var does not mean "any type". It means "work the type out from the right-hand side". The compiler reads 12, settles on int, and the variable is an int from then on.
The compiled output is identical either way. This is a choice about what the next reader sees, nothing more.
var employeeCount = 12; // int
var departmentName = "Payroll"; // string
var monthlyBudget = 48250.75m; // decimal
var recentHires = new List<string>(); // List<string>
var invoice = new Invoice("INV-2041"); // the type is already on the line- Hover over any var in your editor and it reports the type it settled on. Nothing is deferred to run time.
- The last two lines are where var earns its place: the type appears after new, so writing it twice adds length without adding information.
- var monthlyBudget = 48250.75; would be a double, not a decimal. The suffix still matters.
The same declaration, written both ways:
| Explicit type | var | |
|---|---|---|
| What the reader sees | The type, on every line | The expression, with the type implied |
| When the right side names the type | Repeats it: Invoice invoice = new Invoice(); | States it once: var invoice = new Invoice(); |
| When the right side is a method call | Documents what you are holding | Reader has to trust the method name |
| If the expression's type changes later | Build error at the declaration | Variable quietly becomes the new type |
| Declaring without a value | Allowed: decimal total; then assign | Not allowed — there is nothing to infer from |
Guidance that holds up in a real codebase:
- Use var when the right-hand side already names the type, as with new or a cast
- Use the explicit type when the value comes from a method whose name does not reveal what it returns
- Use the explicit type when you want a different one from the inferred one: double rate = 5; where var would give int
- Prefer the explicit type for money and measurements, so the reader can see decimal rather than infer it from a suffix
- Stay consistent inside a file. Alternating styles on neighbouring lines reads as noise
Four terms that get used loosely and mean different things:
- Declaration
- Introducing a name and its type: decimal total;
- Assignment
- Putting a value into a name that already exists: total = 48.50m;
- Initialisation
- Declaring and assigning in one statement. This is what you will write most of the time.
- Definite assignment
- The rule that a local variable must be given a value before anything reads it. C# enforces this at compile time.
Summary
- Every C# variable has a type decided at compile time, and that type never changes
- var infers the type from the right-hand side; it is not a dynamic or universal type
- Explicit types document a value when the expression does not; var removes repetition when it does
- Locals must be assigned before they are read, while fields start at their type's default
Practice
Attempt each one before opening the solution. Getting it wrong first is how the idea sticks.
Try it yourself
Try it yourself
Declare variables for one invoice: the invoice number as text, the number of line items, the net amount, and whether it has been paid. Print a single sentence containing all four.
Write it once with explicit types and once with var, then decide which version you would rather find in six months.
Show solution
Both versions compile to the same thing, so choose on readability. Most people keep the explicit types here because the literals are bare numbers: 4 could be several types, and 1240.50m is only a decimal because of one character at the end.
Where the right-hand side is a constructor call, var removes a genuine repetition. That is the line worth drawing.
string invoiceNumber = "INV-2041";
int lineItemCount = 4;
decimal netAmount = 1240.50m;
bool isPaid = false;
Console.WriteLine(
$"Invoice {invoiceNumber}: {lineItemCount} items, {netAmount} net, paid: {isPaid}");Think about it
Think about it
C# lets you declare a local variable without a value but refuses to let you read it until you assign one.
Why is refusing more useful than quietly setting it to zero?
Show solution
A default would hide the mistake. If you meant to assign a running total and forgot, a silent 0 produces a plausible wrong answer and the program reports nothing unusual.
Refusing to build turns that wrong number into a message with a line number. The cost is that you occasionally write = 0 for a value you know will be set — cheap, for removing an entire category of silent bug.
Fields do get defaults because an object can be built up in stages, and the compiler cannot prove when a field will first be read.
Knowledge check
Nothing is recorded and there is no score. The explanation appears either way.
Saved in this browser only.