Beginner concept · types
var vs explicit types in C#
The most common misconception: var is not dynamic typing. The variable still has exactly one type, chosen by the compiler from the right-hand side — you just didn't write it down.
What var actually does
The type comes from the right-hand side, at compile time. In Visual Studio this program prints the types — and they never change afterward:
var price = 9.99; // double — because 9.99 is a double literal
var count = 42; // int — because 42 is an int literal
var name = "Ada"; // string
Console.WriteLine(price.GetType()); // System.Double
Console.WriteLine(count.GetType()); // System.Int32
Console.WriteLine(name.GetType()); // System.String
(.GetType() reflection isn't in the browser engine's subset — the claims below are verified with checks that do run here.)
The engine's strict type checking proves the same claim live — a var variable behaves exactly like its inferred type:
var x = 9.99; // x is a double from this line on
int y = x; // CS0266: exactly as if you'd written 'double x = 9.99;'
If var were dynamic (like JavaScript), that assignment would have compiled. It didn't — because x is a double in every sense, just inferred.
Two literal traps worth knowing before day one
var a = 7 / 2.0; // double: 3.5
var b = 7 / 2; // int: 3 — integer division, fraction lost!
Console.WriteLine(a);
Console.WriteLine(b);
var faithfully copies whatever the expression produced — including integer division surprises (full story: why 7 / 2 is 3).
When var shines
Use var when the type is already obvious from the same line — then it's pure noise reduction:
var names = new List<string>(); // obviously a List<string>
var dog = new Dog("Rex", 3); // obviously a Dog
var total = price * quantity; // fine when types are simple
The generic-container case is where you feel it most — compare:
Dictionary<string, List<int>> scores = new Dictionary<string, List<int>>(); // typed twice
var scores2 = new Dictionary<string, List<int>>(); // typed once
var scores = new Dictionary>();
scores["Ada"] = new List { 90, 85 };
Console.WriteLine($"Ada has {scores["Ada"].Count} scores");
When the explicit type wins
Write the type out when it is information the reader can't otherwise see:
- Numeric intent:
double average = total / count;documents that you expect a fraction.var average = total / count;silently inheritsintif both are ints — a bug wearing a disguise. - API results:
var user = GetUser(id);forces a reader to hover or jump to find the type.User user = GetUser(id);reads by itself. - Similar-looking types:
decimalvsdoublefor money — the difference matters andvarhides it.
var label = "count: ";
int n = 5;
Console.WriteLine(label + n); // fine: string + int concatenates
var wrong = n = label; // nonsense on purpose: assigning string into int slot
Rules var must follow
- It must have an initializer —
var x;is illegal (what type would x be?). - It can't flip types later — once inferred, it's fixed like any declaration.
- It's not the same as JavaScript's
var, and notdynamic— C#'sdynamicis a different (and rare) keyword that skips compile-time checking.
Team conventions, compressed
| Situation | Use | Why |
|---|---|---|
new on the same line | var | Type is spelled on the right already |
| Numeric declarations | explicit | int vs double is load-bearing information |
| Method-call results | explicit (or a good name) | Reader shouldn't have to look it up |
| LINQ / complex generics | var | The full type name would be longer than the logic |
Most style guides (including Microsoft's) land on: use var when the right side makes the type obvious, otherwise spell it out. When two experienced developers disagree, it's almost always about what counts as "obvious."