skipnothing/.NET Platform

Value Types vs Reference Types

Write `b = a`, then `b.X = 9`. Whether `a.X` reads 9 or stays untouched comes down to one keyword you picked pages earlier, `struct` or `class`, and nothing else about those two lines tells you which way it goes.

  • One keyword decides whether = hands you an independent twin or a second name for the same object.
  • object o = i; shows no new, yet it boxes the value onto the heap as a separate copy.
  • Two freshly built objects with identical fields are equal if they're structs and unequal if they're classes.
BUILDS ON
01

Value copy versus handle copy

The previous topic settled where bytes live: lifetime decides that, not the keyword. So what does writing struct instead of class actually buy you? It decides one thing: what = copies.

struct PointS { public int X, Y; }
class  PointC { public int X, Y; }

var a = new PointS { X = 1 };
var b = a;            // copies the whole value

var c = new PointC { X = 1 };
var d = c;            // copies only the handle

With PointS, b = a duplicates every field into a second, independent instance. You now have two values that happen to be equal and will drift apart the moment you touch one. With PointC, d = c copies a pointer: c and d are two names for one object on the heap. No second object was made.

That single difference is the entire definition. A value type contains its data, so assignment, passing an argument, and returning a result each copy the whole instance. A reference type contains a reference to its data, so the same operations copy only the reference. Every other behavior in this topic, shared mutation, boxing, what equality means by default, is a consequence of this one rule.

ONE ASSIGNMENT, TWO OUTCOMES

Keep going, sign up to unlock the rest

4 more parts in this topic, plus 25+ more topics in .NET Platform.

Sign up, it's freeSee the full .NET Platform
Memory & the Type System0/6#6 Stack vs Heap
#8 The Garbage Collector