← Back

Class vs Record vs Struct in C#: Understanding the Differences

2026-01-17 13:55 · 👁 47845

#c#

Class vs Record vs Struct in C#: Understanding the Differences

Choosing between class, record, and struct isn’t just style — it changes allocation, equality, copying, immutability defaults, and how your types behave in collections and APIs.

Here’s the practical breakdown 👇


1) The mental model

class

  • Reference type (usually allocated on the managed heap)
  • Variables hold a reference to the same object
  • Best for mutable, identity-based objects (entities, services, complex graphs)

record

  • Primarily about value-based equality and with-expressions
  • Can be reference type (record) or value type (record struct)
  • Best for data models where equality should be based on contents

struct

  • Value type (stored inline in arrays/fields; may be stack-allocated in some cases)
  • Assignments create a copy
  • Best for small, immutable-ish, performance-sensitive data (points, money, IDs)

2) Equality: the biggest “gotcha”

class reference equality by default

Two objects with same data are not equal unless you override equality.

recordvalue equality by default

Two records with the same data are equal (by generated Equals/GetHashCode).

structvalue equality, but…

Struct equality exists, but:

  • can be slower depending on fields
  • mutable structs can create chaos in collections

3) Copy semantics: who gets copied?

class / record (reference type)
var a = new Person("Diego");
var b = a;
b.Name = "Other";
Console.WriteLine(a.Name); // "Other" (same instance)
struct / record struct (value type)
var a = new Point(1, 2);
var b = a;
b = b with { X = 99 };
Console.WriteLine(a.X); // 1 (copied)

4) Immutability defaults (and what people assume)

class

Mutable by convention (unless you enforce immutability manually)

record

Encourages immutability:

public record Person(string Name, int Age);
  • init-only properties
  • with cloning is first-class

struct

Can be immutable, but you must design it that way. Rule of thumb: if you use structs, prefer readonly struct.


5) When to use what (real-world guidance)

Use class when:

✅ you model entities with identity (e.g., User, Order)
✅ you need polymorphism, inheritance, large graphs
✅ the object is mutable by design

Use record when:

✅ you pass data around (DTOs, messages, query results)
✅ you want value equality and easy cloning
✅ you want clean “data-centric” code

Use struct when:

✅ the type is small (commonly under ~16–32 bytes)
✅ it’s immutable and frequently created
✅ you want to reduce allocations in hot paths


6) Quick cheat sheet

  • Identity matters?class
  • Data + value equality matters?record
  • Tiny value, performance, avoid allocations?readonly struct / record struct

7) Common pitfalls

❌ Mutable structs

They copy silently and can break expectations.

❌ Large structs

Copying big structs repeatedly can be slower than a class reference.

❌ Using record for entities

Record’s value equality can be wrong for identity-based domain entities.


Takeaway

  • Class = identity + reference behavior
  • Record = data + value equality + great ergonomics
  • Struct = value semantics + performance (when designed carefully)

Rejoining the server...

Rejoin failed... trying again in seconds.

Failed to rejoin.
Please retry or reload the page.

The session has been paused by the server.

Failed to resume the session.
Please reload the page.