Types · value vs reference

struct vs class in C#

The declaration keyword matters less than the assignment semantics: a class variable holds a reference to one shared object; a struct variable holds its own copy. Everything else follows from that.

class: two names, one object

Assigning a class variable copies the reference, not the object. Both names point at the same box:

class Dog
{
    public string Name;
    public Dog(string name) { Name = name; }
}

Dog a = new Dog("Rex");
Dog b = a;            // b is a SECOND NAME for the same object
b.Name = "Max";       // renaming through b…
Console.WriteLine(a.Name);   // …renamed it for a too
class Dog
{
    public string Name;
    public Dog(string name) { Name = name; }
}

Dog a = new Dog("Rex");
Dog b = new Dog("Rex");   // a genuinely new, separate object
b.Name = "Max";
Console.WriteLine(a.Name);      // untouched
Console.WriteLine(a == b);      // == compares REFERENCES: different objects → False
                                // (same content, different identity)

struct: assignment makes a copy

Structs flip the semantics. Assigning a struct copies the whole value — the two variables are independent from that moment:

struct Point
{
    public int X;
    public Point(int x) { X = x; }
}

Point a = new Point(1);
Point b = a;        // FULL COPY — b has its own storage
b.X = 99;

Console.WriteLine(a.X);   // 1   — a was never touched
Console.WriteLine(b.X);   // 99

Honesty note: the browser engine currently treats structs like classes (reference semantics) — that exact program in Visual Studio prints 1 and 99 as shown. The concept stands; verify copy behavior in a real compiler until the engine grows value semantics.

The gotcha this explains

Ever changed a field through one variable and been surprised another variable "saw" the change? That was reference aliasing. And its mirror: changed a struct field inside a method, and the caller's copy didn't update? Value copying. Both are the correct behavior for their kind — the bug is expecting the other kind:

Scenarioclassstruct
b = a; copies…the referencethe whole value
Mutating through b affects a?Yes — same objectNo — separate copy
a == b means…same identitysame field values (if == is defined)
Lives…on the heap, garbage-collectedinline (stack or inside its owner)

Which one to pick?

The practical rule most codebases follow:

One-minute self-test

Run this in the playground and predict the output before pressing Run — it's the aliasing demo from above with the names swapped:

Dog x = new Dog("One");
Dog y = x;
y = new Dog("Two");
Console.WriteLine(x.Name);   // predict: One or Two? (reference vs object)

If you said "One" — assigning new Dog("Two") to y re-points y's reference; it never touches the object x names. Related reading: var vs explicit types.