In today’s C# landscape, developers are continually looking for ways to simplify code while improving maintainability.
That’s where Records, introduced in C# 9, come into play.
But how do they differ from the good old Classes, and when should you choose one over the other? Let’s dive in and explore the differences between these two.
The core differences between Classes and Records
Classes in C#
Classes have been the go-to structure in object-oriented programming for defining complex data types.
They can contain fields, properties, methods, and events, offering full flexibility for encapsulating behavior and state.
public class Person
{
// Properties
public string FirstName { get; set; }
public string LastName { get; set; }
// Constructor
public Person(
string firstName,
string lastName)
{
FirstName = firstName;
LastName = lastName;
}
// Overrides
public override string ToString()
=> $"{FirstName} {LastName}";
}
// Instance
var person = new Person("John", "Doe");
// Use
Console.WriteLine(person);
// Outputs: John Doe
Records in C#
Records were introduced to simplify creating immutable data types. While they look similar to classes, they focus more on data immutability and value-based equality, making them perfect for data-centric programming models.
public record Person(string FirstName, string LastName);
// Instance
var person = new Person("John", "Doe");
// Use
Console.WriteLine(person);
// Outputs: John Doe
Notice the concise syntax and the immutable nature by default. With record, properties are immutable unless explicitly modified.
Key features that make records stand out
Value equality in records
One of the main differences between classes and records is how equality works. In classes, objects are compared by reference, whereas records compare by value.
// CLASS
var person1 = new Person("John", "Doe");
var person2 = new Person("John", "Doe");
Console.WriteLine(person1 == person2);
// Outputs: False// RECORD
var record1 = new Person("John", "Doe");
var record2 = new Person("John", "Doe");
Console.WriteLine(record1 == record2);
// Outputs: TrueImmutability by Default
In records, the properties are immutable by default. This means once you create a record, its properties cannot be changed, making it ideal for scenarios where you need safety in data consistency.
var record = new Person("John", "Doe");
// record.FirstName = "Jane";
// Compile-time error, cannot modify propertiesIf needed, you can make a modified copy using the with expression:
var modifiedRecord = record with {
FirstName = "Jane"
};
Console.WriteLine(modifiedRecord);
// Outputs: Jane DoeConcise Syntax with Positional Parameters
Records allow you to define properties concisely, especially when working with data-focused types.
public record Address(string Street, string City, string ZipCode);This reduces boilerplate code, making records an excellent choice for DTOs (Data Transfer Objects).
When to use Classes and when to use Records
Use Classes when you need:
- Mutable state.
- Complex behavior beyond storing data.
- Reference-based equality (e.g., comparing object references).
Use Records when:
- Your focus is on immutability and value-based equality.
- You need concise syntax for data-centric models.
- You want the benefits of immutability with value comparison built-in.
Conclusion
Both classes and records serve vital roles in C# development. Classes offer flexibility and are suitable for a wide range of applications, while records provide a streamlined way to handle immutable data with value-based equality.
Understanding when to use each will help you write more efficient and maintainable code.
