Skip to Content
Course content

7: Variables and Value vs Reference Types

Click on the "Edit" button in the top corner of the screen to edit your slide content.

I want you to imagine two different ways of sharing information. First, imagine I have a piece of paper with the number "42" written on it. I take that paper to a photocopier, make a copy, and hand it to you. Now we both have a piece of paper that says "42." If you take your pen and scratch out your number and change it to "100," my paper still says "42." We have two completely independent copies of the value.

Now, imagine a different scenario. Instead of a number, I have a link to a shared Google Doc. I email that link to you. We both have the link, but there is only one actual document living on the server. If you click the link and delete the first paragraph, when I click my link, that paragraph is gone for me too. We aren't sharing the document itself; we're sharing a reference (the link) to the document.

The Self-Contained Value Types

In C#, "Value Types" are like that photocopy. When you assign one value type to another, you're creating a brand new copy of the data. This usually happens with simple things like int, bool, double, and char, as well as structs.

int myScore = 10;
int yourScore = myScore; // A photocopy is made here
yourScore = 20;

Console.WriteLine(myScore); // Still 10
Console.WriteLine(yourScore); // 20

These are stored on something called the "Stack." I won't bore you with the deep memory architecture yet, but for now, just know that the Stack is fast, efficient, and handles these small, fixed-size pieces of data perfectly.

Pointing to the Heap

Reference Types are the Google Doc links. The most common ones you'll deal with are class, string, and array. When you create an instance of a class, the actual object (the data) lives in a large pool of memory called the "Heap." Your variable doesn't actually hold the object; it holds the memory address of where that object is sitting.

This is where things get interesting. If you assign one reference variable to another, you aren't copying the object; you're just copying the link.

public class Player {
    public string Name;
}

// ... inside a method ...
Player player1 = new Player();
player1.Name = "Alice";

Player player2 = player1; // We just copied the link, not the Player object
player2.Name = "Bob";

Console.WriteLine(player1.Name); // It says "Bob"!

I've seen plenty of junior devs spend hours debugging a "ghost" bug where a value changed unexpectedly, only to realize they were modifying a reference type that was being used in three other places in the code. It's a rite of passage, honestly.

The Strange Case of Strings

You might notice that string is a reference type, but it often feels like a value type. If you change a string, it doesn't seem to affect other variables pointing to it. This is because strings are immutable. In C#, you can't actually "change" a string; whenever you modify one, C# quietly creates a whole new string object in the background. It's a special exception designed to prevent the exact kind of headache I mentioned above.




📋 Practical Task

The Shared Bank Account Bug Fix

You are reviewing code for a banking app. A developer tried to create a "Backup" of a user's account before processing a transaction, but they accidentally used a reference type, and now the backup is changing whenever the main account changes. This is a classic reference type mistake.

Your Task: Fix the Account logic so that the backupAccount remains a snapshot of the original values and is not affected by changes made to the mainAccount.

using System;

public class Account {
    public decimal Balance;
}

public class Program {
    public static void Main() {
        Account mainAccount = new Account();
        mainAccount.Balance = 100.00m;

        // BUG: This currently just copies the reference (the link)
        Account backupAccount = mainAccount; 

        // Processing a withdrawal
        mainAccount.Balance -= 40.00m;

        Console.WriteLine($"Main Balance: {mainAccount.Balance}"); // Should be 60.00
        Console.WriteLine($"Backup Balance: {backupAccount.Balance}"); // Should be 100.00, but currently prints 60.00
    }
}

Hint: To fix this, you need to ensure backupAccount points to a brand new object in memory, but starts with the same values as mainAccount.

Rating
0 0

There are no comments for now.

to be the first to leave a comment.