100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
C#

Variables and Data Types

Covers how C# declares and initializes variables, its built-in value and reference types, type inference with var, and the difference between static and dynamic typing.

C# FoundationsBeginner9 min readJul 9, 2026
Analogies

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.

csharp
// 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 operator

Unlike 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.
  • var is compile-time type inference, not dynamic typing — the underlying type is fixed and cannot change.
  • decimal should be used for currency/financial values to avoid the rounding imprecision of float/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

Was this page helpful?

Topics covered

#CStudyNotes#Programming#VariablesAndDataTypes#Variables#Data#Types#Built#StudyNotes#SkillVeris#ExamPrep