What is a record in C# and how is it different from a class?

C# Type System Intermediate 2–3 Yrs3–5 Yrs Conceptual 1 min read

Quick Answer

A record is a reference type (or record struct for a value type) designed for immutable data. The compiler generates value-based Equals/GetHashCode (two records are equal if all their fields match), a readable ToString, a deconstructor, and support for non-destructive mutation with with.

A record is a type built for immutable data. When I write record Person(string First, string Last), the compiler generates value-based equality — two records with the same values are equal, unlike a class which compares by reference — plus a good ToString, a deconstructor, and the with expression for making a modified copy. I use records for DTOs, API request/response models, domain value objects and events — anywhere I care about the data, not the identity. I keep classes for things with identity or mutable behaviour.

public record Person(string First, string Last); gives you:

  • Value equality — new Person("A","B") == new Person("A","B") is true (a class would compare by reference).
  • Immutability — positional properties are init-only.
  • with expressions — person with { Last = "C" } creates a copy with one change.
  • Nice ToString — Person { First = A, Last = B }.
  • Deconstruction — var (f, l) = person;.

Use records for DTOs, API models, events, value objects and anything you compare by content. Use a class when the type has identity, mutable state or behaviour-heavy logic. record struct combines value semantics with stack allocation for small data.

C# — record
public record Money(decimal Amount, string Currency);

var a = new Money(10m, "USD");
var b = new Money(10m, "USD");
Console.WriteLine(a == b);            // True — value equality

var c = a with { Amount = 20m };     // copy with one change
Console.WriteLine(c);                 // Money { Amount = 20, Currency = USD }