← Open in the full interactive course (progress tracking, search & more)

Storing data that changes — and data that stays the same — in C#.

Imagine you're building a calculator app. You need to store the numbers the user enters, the result of each operation, and maybe a fixed value like PI that never changes. Every time the user presses a button, the numbers in memory change — but PI stays exactly the same.

That's the core difference between variables and constants in C#. Variables hold data that can change as your program runs. Constants hold data that stays fixed forever.

Every C# program — from a simple console app to a massive enterprise system — uses variables and constants constantly. Understanding them is the first step toward writing real code that works with data.

What Is It?

The Simple Explanation

Variable = A named storage location in memory whose value can change during program execution.

Constant = A named storage location whose value is fixed at compile time and cannot change afterward.

The Technical Definition

Variables are named memory locations that store values. You declare a variable by specifying its type and name, and you can assign a value to it. The value can be changed any number of times during the program's lifetime.

Constants are values that are known at compile time and do not change for the entire lifetime of the program. They are declared using the const keyword and must be assigned a value at declaration. The compiler replaces constant references with their literal values during compilation.

Variable = Can change Constant = Cannot change
Both store data in memory — but one is mutable, the other immutable.

Why Does It Exist?

The Problem

When you write a program, you need to work with data. A user's name, a bank balance, the current time, a product price — these are all pieces of information your program needs to store, retrieve, and manipulate.

Imagine if you had to remember the memory address of every piece of data you used. It would be nearly impossible to write any program larger than "Hello, World!"

The Solution

Variables give you a named way to refer to data. Instead of remembering that the user's age is at memory address 0x7FFD8A3F9C10, you can simply use the name age. Constants give you a way to give meaningful names to fixed values — so instead of writing 3.14159 everywhere, you write PI.

The key insight

Variables and constants are how your program "remembers" data. Without them, every piece of information would have to be re-entered or recalculated every time it was needed.

Big Picture

Here's how variables and constants fit into the C# type system and memory:

DATA STORAGE IN C#
Variables
Value Types
  • Store data directly on the stack
  • Examples: int, bool, double, struct
Reference Types
  • Store a reference on the stack, data on the heap
  • Examples: string, object, class, array
Constants (const)
  • Inlined by the compiler — no memory allocation at runtime
  • Only value types and string can be const
  • Must be assigned at declaration
Read‑only Fields (readonly)
  • Assigned at declaration or in the constructor
  • Can be reference types
  • Not inlined — accessed like a field

How It Works

Let's trace what happens when you declare and use variables and constants in C#:

Step 1 — Declare a variable

int age;  // Declaration — memory is reserved, but no value is set yet

You tell the compiler: "I need a storage location named age that can hold an int." The compiler reserves memory for it.

Step 2 — Initialize the variable

age = 25;  // Assignment — the value 25 is stored in the reserved memory

You write a value into the memory location. Now age holds the value 25.

Step 3 — Declare and initialize a constant

const double PI = 3.14159;  // Must be assigned at declaration

The compiler sees PI and replaces every use of PI with 3.14159 at compile time. No memory is allocated at runtime.

Step 4 — Use the variable and constant

double circumference = 2 * PI * radius;  // PI is replaced with 3.14159

The variable radius holds a value from user input or calculation. The constant PI provides the fixed mathematical value.

Simple Example

Here's a complete C# program showing variables and constants in action:

        // ── Variables ──
        string userName = "Alice";   // Can change later
        int score = 0;                // Starts at 0, can increase
        bool isGameOver = false;      // Tracks game state

        // ── Constants ──
        const int MAX_SCORE = 100;      // Fixed maximum
        const string GAME_TITLE = "Super C# Adventure";

        // ── Using them ──
        Console.WriteLine($"Welcome to {GAME_TITLE}, {userName}!");
        score += 10;                 // Variable changes

        if (score >= MAX_SCORE)        // Constant used in condition
        {
            isGameOver = true;
            Console.WriteLine($"You win, {userName}!");
        }
    

What's happening:

Real-World Example

Consider an e‑commerce checkout system. Here's how variables and constants would be used:

        // ── Constants (business rules that never change) ──
        const decimal TAX_RATE = 0.08m;              // 8% sales tax
        const decimal FREE_SHIPPING_THRESHOLD = 50.00m;
        const decimal STANDARD_SHIPPING = 5.99m;

        // ── Variables (data that changes per order) ──
        string customerName = "Jane Doe";
        var cartItems = new List<Product>();     // C# 14: collection expression
        decimal subtotal = 0.00m;
        decimal tax = 0.00m;
        decimal shipping = 0.00m;
        decimal total = 0.00m;

        // ── Calculate order totals ──
        foreach (var item in cartItems)
        {
            subtotal += item.Price * item.Quantity;   // Variable changes
        }

        tax = subtotal * TAX_RATE;                    // Constant used

        if (subtotal >= FREE_SHIPPING_THRESHOLD)      // Constant used
        {
            shipping = 0.00m;
        }
        else
        {
            shipping = STANDARD_SHIPPING;            // Constant used
        }

        total = subtotal + tax + shipping;            // Final variable

        // ── Output ──
        Console.WriteLine($"Order for {customerName}: ${total:F2}");
    

What's happening:

Analogy

Variables are like labelled boxes

You have a box with a label — age. You can put a number in it, take it out, and replace it with a different number later. The box stays the same; the contents change.

Constants are like engraved plaques

You have a plaque with PI = 3.14159 engraved into it. You can read it, but you can never change it. The value is fixed forever.

How the analogy maps to code

Under the Hood

Let's look at what actually happens in memory and at compile time when you use variables and constants:

VARIABLE & CONSTANT LIFECYCLE
1. YOU WRITE CODE
int age = 25;
const double PI = 3.14159;
2. COMPILER PROCESSES THE CODE
3. AT RUNTIME (Variable)
4. AT RUNTIME (Constant)
5. WHEN THE VARIABLE CHANGES

Memory Layout: Stack vs Heap

Stack (fast, short‑lived)
age = 25 // int — stored directly
score = 0 // int — stored directly
isGameOver = false // bool — stored directly
userName = 0x7F9A4C20 // reference to heap string
Heap (slower, long‑lived)
"Alice" // string data on the heap
Constants (no runtime memory)
MAX_SCORE is inlined as 100 everywhere it's used
GAME_TITLE is inlined as "Super C# Adventure" everywhere

Common Confusion

const vs readonly

const ≠ readonly

const — Compile‑time constant. Inlined. Only value types and string. Must be assigned at declaration.

readonly — Runtime constant. Not inlined. Can be reference types. Can be assigned in the constructor.

Remember: readonly is "set once, then never changed" — but it's not a compile‑time constant. It's evaluated at runtime.

var vs explicit type

var ≠ "variant" or "dynamic"

var is statically typed — the compiler infers the type from the initialization expression. It's not a "loose" type like dynamic or JavaScript's var.

            var name = "Alice";   // name is string — compiler knows this
            name = 42;              //  Compiler error: can't assign int to string
        

Use var when the type is obvious from the right‑hand side. Use explicit types when the type is not obvious or when you want to be explicit for clarity.

Common Mistakes

Mistake 1 — Using a variable without initializing it
                    int count;
                    Console.WriteLine(count);  //  Compiler error: unassigned local variable
                

Fix: Always initialize variables before reading them.

                    int count = 0;
                    Console.WriteLine(count);  //  Works — outputs 0
                
Mistake 2 — Trying to reassign a constant
                    const double PI = 3.14159;
                    PI = 3.14;  //  Compiler error: cannot assign to const
                

Fix: Use a variable if the value needs to change, or use readonly if it's set once in a constructor.

                    double pi = 3.14159;  // Variable — can change
                    pi = 3.14;  //  Works
                
Mistake 3 — Using const for runtime values
                    const DateTime Now = DateTime.Now;  //  Compiler error: DateTime.Now is not a compile-time constant
                

Fix: Use static readonly for runtime‑evaluated values.

                    static readonly DateTime Now = DateTime.Now;  //  Works
                
Mistake 4 — Confusing value types and reference types
                    int a = 5;       // Value type — stored on stack
                    int b = a;       // Copy of value — b is 5, a is 5
                    a = 10;          // b is still 5 — separate copies

                    string s1 = "Hello";  // Reference type — stored on heap
                    string s2 = s1;    // Both point to the same string object
                    s1 = "Goodbye";  // s2 still points to "Hello" — strings are immutable
                

Fix: Understand that value types copy data; reference types copy references.

When Should I Use It?

Use variables when:

Use constants when:

Use readonly when:

Best practice: Prefer readonly over const when you're not certain the value is truly compile‑time constant. readonly gives you more flexibility and avoids versioning issues when constants change.

Mental Model

Variable = Box with a label
    — You can put something in, take it out, and put something else in.
    — The label (name) stays the same; the contents (value) change.

Constant = Engraved plaque
    — The value is carved in stone. You can read it, but you can never change it.
    — The compiler writes the value directly into your code at compile time.

readonly = Locked box with a key
    — You set the value once (at construction) and then it's locked forever.
    — The value is determined at runtime, not compile time.

Key Takeaway


Check Your Understanding

You've seen how variables hold data that can change and constants hold fixed values. Let's test your understanding of when and how to use each.

1. Which of the following correctly declares a constant in C#?

Show answer

Correct: B

Why B is correct: The const keyword is used to declare a compile‑time constant. The value must be assigned at declaration and cannot change afterward.

Why A is incorrect: This declares a variable, not a constant. PI could be reassigned later.

Why C is incorrect: readonly is a runtime constant. It can be assigned in the constructor, not just at declaration. It's not a compile‑time constant like const.

Why D is incorrect: static makes a variable belong to the type rather than an instance, but it's still a variable that can change.

Reinforcement: const is for values that are truly fixed and known at compile time. Use readonly when the value is set at runtime but then never changes.

2. What will this code output?

            int x = 5;
            int y = x;
            x = 10;
            Console.WriteLine(y);
        
Show answer

Correct: B

Why B is correct: int is a value type. When you assign y = x, you create a copy of the value. Changing x to 10 doesn't affect y, which remains 5.

Why A is incorrect: This would be true if int were a reference type, but it's a value type. The two variables are independent.

Why C is incorrect: The code is perfectly valid and compiles successfully.

Why D is incorrect: y was initialized to the value of x (which was 5 at that time), not 0.

Reinforcement: Value types (like int, bool, double, struct) copy data when assigned. Reference types (like string, class, array) copy references. This is a crucial distinction in C#.

3. You're building a banking application. The interest rate is set by the central bank and rarely changes. The account balance changes with every deposit and withdrawal. Which approach is correct?

Show answer

Correct: B

Why B is correct: The interest rate is a fixed business rule that can be a compile‑time constant (const) if known at compile time, or readonly if loaded from configuration. The account balance must be a variable because it changes constantly.

Why A is incorrect: Account balance changes frequently — it cannot be a constant.

Why C is incorrect: Account balance cannot be a constant for the same reason. Interest rate could be either a constant or a variable, but it's better as a constant (or readonly) since it shouldn't change arbitrarily.

Why D is incorrect: readonly means the value is set once and never changes — that works for interest rate but not for account balance, which changes with every transaction.

Reinforcement: Choose const or readonly for values that are fixed. Use variables for values that change over time. Always match the storage mechanism to the data's behaviour.

4. What happens if you try to declare a constant using a value that's not known at compile time?

Show answer

Correct: C

Why C is correct: const values must be known at compile time. The compiler must be able to evaluate the expression. For example, DateTime.Now is not a compile‑time constant, so const DateTime Now = DateTime.Now; will produce a compiler error.

Why A is incorrect: This is not a warning situation — it's a hard compile‑time error.

Why B is incorrect: const can't use runtime values. This is the whole point of readonly — for runtime‑evaluated values.

Why D is incorrect: The compiler doesn't "downgrade" a constant to a variable. You'll get an error and the code won't compile.

Reinforcement: If you need a value that's determined at runtime but won't change afterward, use readonly instead of const. readonly values are set at runtime (in the constructor) and then locked.

5. Consider this code snippet. Which statement about the userName variable is true?

            string userName = "Alice";
            userName = "Bob";
            Console.WriteLine(userName);
        
Show answer

Correct: C

Why C is correct: userName is a variable that holds a reference to a string. When you reassign it from "Alice" to "Bob", the variable now points to a different string object. The string "Alice" remains immutable, but the variable changed what it points to.

Why A is incorrect: You can reassign a string variable to a new string value. The string itself is immutable, but the variable can change.

Why B is incorrect: The output is "Bob" because the variable was reassigned before the WriteLine call.

Why D is incorrect: This would only happen with concatenation (e.g., userName += "Bob"), not with reassignment.

Reinforcement: "Immutable" means the object itself can't change, not that the variable can't change. This is a very common source of confusion for beginners. Strings are immutable, but string variables are still variables — they can be reassigned.

You've mastered variables and constants — the foundation of working with data in C#!


dotnetmadeeasy.com — Learn C# and .NET, the right way.