Variables and Data Types
C# is a statically and strongly typed language: every variable has a type known at compile time, and that type cannot silently change or accept incompatible values without an explicit conversion. This catches a large class of bugs before the program ever runs, at the cost of requiring more upfront type declarations than dynamically typed languages like Python or JavaScript. C#'s type system splits into two broad categories — value types, which store data directly, and reference types, which store a pointer to data on the managed heap — and understanding that split is fundamental to writing correct, efficient C#.
Cricket analogy: A cricket scoreboard that only accepts numeric runs entries catches a typo like entering 'four' as text before the match starts, unlike a casual hand-scored notebook where anything can be scribbled in; knowing whether a stat is a fixed number or a shared team record is fundamental to scoring correctly.
Built-in Value Types
Value types include numeric types (int, long, float, double, decimal), bool, char, and struct-based types in general. When you assign a value type to another variable, or pass it to a method, the entire value is copied. Value types are typically allocated on the stack (though they can live on the heap when boxed or embedded in a reference type), which makes them fast to allocate and deallocate. int is a 32-bit signed integer; long is 64-bit; decimal is a 128-bit high-precision type ideal for currency, because it avoids the binary floating-point rounding errors that float/double exhibit.
Cricket analogy: A player's individual ball-by-ball score is like an int, small, fixed, and fast to track, while a career total spanning decades needs a long-sized ledger; and just as a team keeps decimal precision for prize money splits to avoid rounding disputes, decimal avoids the rounding errors float/double would cause.
Reference Types and Type Inference
Reference types — classes, arrays, delegates, and strings — store a reference (pointer) to an object allocated on the managed heap. Assigning a reference-type variable to another copies the reference, not the underlying object, so both variables point to the same data. The var keyword lets the compiler infer a variable's static type from its initializer at compile time; it is not dynamic typing — var x = 5; makes x a genuine, fixed int forever, just written more concisely. This is distinct from dynamic, which defers type checking to runtime.
Cricket analogy: Two commentators sharing one live scoring app both see updates instantly since they're viewing the same underlying feed, like reference types; declaring 'var score = 250' locks the type as a fixed number forever even though you didn't write 'int' explicitly, unlike a loosely kept notebook where a 'dynamic' entry could later become text.
// Value types: copied by value
int score = 100;
int copy = score;
copy = 50;
Console.WriteLine(score); // still 100 — score and copy are independent
// Reference types: copied by reference
var order = new List<string> { "Widget", "Gadget" };
var alias = order;
alias.Add("Gizmo");
Console.WriteLine(order.Count); // 3 — order and alias point to the same list
// Type inference with var — still statically typed under the hood
var total = 42; // inferred as int
var label = "Total"; // inferred as string
var price = 19.99m; // inferred as decimal (note the 'm' suffix)
// Nullable value types
int? maybeCount = null;
Console.WriteLine(maybeCount ?? -1); // prints -1 via the null-coalescing operatorUnlike Java, C# has true value types (structs) that programmers can define themselves, not just a fixed set of primitives. DateTime, TimeSpan, and Guid are all structs in the .NET base class library, meaning they behave like int in terms of copy semantics — assigning one copies its full contents rather than sharing a reference.
A frequent source of bugs is assuming var means 'dynamically typed' or 'loosely typed' — it does not. The compiler fixes the type at the point of declaration based on the initializer expression, and var cannot be used without an initializer (var x; is a compile error, since there is nothing to infer the type from).
- C# is statically and strongly typed; every variable's type is fixed at compile time.
- Value types (int, bool, struct, etc.) copy their full data on assignment; reference types (class, array, string) copy only a pointer.
varis compile-time type inference, not dynamic typing — the underlying type is fixed and cannot change.decimalshould be used for currency/financial values to avoid the rounding imprecision offloat/double.- Nullable value types (
int?,bool?) let normally non-nullable value types represent an absent value. - Custom value types can be defined with
struct, giving copy-by-value semantics to user-defined data.
Practice what you learned
1. What happens when a value-type variable is assigned to another variable?
2. What is the primary reason to use `decimal` instead of `double` for monetary values?
3. Which statement about `var` is correct?
4. How do you declare a variable of type int that can also hold null?
5. Which of these is a reference type in C#?
Was this page helpful?
You May Also Like
Operators in C#
A tour of C#'s arithmetic, comparison, logical, assignment, and null-conditional operators, including precedence rules and operator overloading basics.
Nullable Reference Types
See how C# 8's nullable reference types add compile-time null-safety annotations on top of the runtime's existing nullable value type system.
Arrays and Lists
Compare C#'s fixed-size arrays with the dynamically resizable List<T>, covering allocation, performance characteristics, and when to reach for each.
Hello World and Project Structure
Breaks down the anatomy of a minimal C# console project — Program.cs, the .csproj file, and how top-level statements simplify the classic Hello World example.
Related Reading
Related Study Notes in Programming
Browse all study notesApache Spark Study Notes
Programming · 30 topics
ProgrammingApache Flink Study Notes
Programming · 30 topics
ProgrammingHadoop Study Notes
Programming · 30 topics
ProgrammingSnowflake Study Notes
Programming · 30 topics
ProgrammingApache Airflow Study Notes
Programming · 30 topics
Programmingdbt (Data Build Tool) Study Notes
Programming · 30 topics