What are records in C# and how do they differ from classes?
Discover what records are in C#, how value equality and 'with' expressions work, and how records differ from classes for building immutable data models.
Expected Interview Answer
Records are a C# 9 reference type (with a record struct value-type variant) built for immutable data models, providing value-based equality, concise positional syntax, non-destructive copying with 'with', and a built-in ToString — features a normal class does not give you by default.
A regular class uses reference equality, so two instances with identical data are considered different unless you override Equals and GetHashCode yourself. A record instead compares by the values of its members, auto-generates those overrides, and supports the 'with' expression to create a modified copy while leaving the original untouched. Records encourage immutability through init-only properties and are ideal for DTOs, domain values, and data transfer. Under the hood a record is still a class (or struct), so you choose records when identity should be based on data rather than object reference.
- Value-based equality generated automatically
- Concise positional syntax for data models
- Non-destructive copying with the 'with' expression
- Built-in readable ToString implementation
- Encourages immutability via init-only properties
AI Mentor Explanation
A class is like identifying players by their squad number — two players with identical stats are still different because the number differs. A record is like judging by the full scorecard: two innings with the exact same runs, balls, and dismissals are treated as equal because the data itself matches, not the label attached to it.
Step-by-Step Explanation
Step 1
Declare a record
Use positional syntax like 'record Person(string Name, int Age);' for a concise immutable model.
Step 2
Get value equality free
Two records with the same member values compare equal via the auto-generated Equals and GetHashCode.
Step 3
Copy non-destructively
Use 'var older = person with { Age = person.Age + 1 };' to make a modified copy without mutating the original.
Step 4
Read the built-in ToString
Records print their type and members, e.g. 'Person { Name = Ada, Age = 36 }', with no extra code.
Step 5
Choose record vs class
Pick a record when identity is defined by data (DTOs, values); pick a class when identity or heavy mutable state matters.
What Interviewer Expects
- Understanding value equality versus reference equality
- Knowing the 'with' expression for non-destructive copying
- Awareness of positional records and init-only properties
- That records are still reference types (record struct for value types)
- Good use cases like DTOs and immutable domain models
Common Mistakes
- Thinking records are always immutable — mutable properties are still allowed
- Believing a record is a value type by default (it is a reference type unless record struct)
- Not knowing records generate Equals, GetHashCode, and ToString automatically
- Confusing 'with' expressions with in-place mutation
- Assuming records replace classes for all scenarios
Best Answer (HR Friendly)
“Records are a special kind of C# type made for holding data. Unlike a normal class, two records are considered equal when their data matches, and you can easily make a slightly changed copy without altering the original — which makes them great for simple, reliable data objects.”
Code Example
public record Person(string Name, int Age);
var a = new Person("Ada", 36);
var b = new Person("Ada", 36);
// Value equality: true (a class would print False)
Console.WriteLine(a == b);
// Non-destructive copy leaves 'a' untouched
var older = a with { Age = 37 };
Console.WriteLine(older); // Person { Name = Ada, Age = 37 }
Console.WriteLine(a); // Person { Name = Ada, Age = 36 }Follow-up Questions
- What is the difference between a record and a record struct?
- How does the 'with' expression work under the hood?
- Can records have mutable state, and is that a good idea?
- How do records implement value equality internally?
- When would you still prefer a class over a record?
MCQ Practice
1. How do two records with identical member values compare with ==?
Records use auto-generated value-based equality, so two records with the same member values are equal.
2. What does the 'with' expression do on a record?
The 'with' expression performs non-destructive copying, producing a new record with specified members changed.
3. By default, a 'record' declared without 'struct' is a:
A plain record is a reference type; record struct is the value-type variant introduced in C# 10.
Flash Cards
What kind of equality do records use? — Value-based equality — two records are equal when their member values match.
What does the 'with' expression do? — Creates a non-destructive copy of a record with selected members changed, leaving the original intact.
Is a record a value type or reference type? — A plain record is a reference type; use 'record struct' for a value type.
What does a record generate for you? — Equals, GetHashCode, a readable ToString, and (for positional records) a constructor and deconstructor.
When should you use a record? — For immutable data models like DTOs and domain values where identity is based on data, not reference.