0
0
CsharpComparisonBeginner · 4 min read

Record vs Class in C#: Key Differences and When to Use Each

In C#, a record is a reference type designed for immutable data with built-in value-based equality, while a class is a reference type typically used for mutable objects with reference-based equality. Records simplify data modeling by automatically providing equality and immutability features, unlike classes which require manual implementation.
⚖️

Quick Comparison

This table summarizes the main differences between record and class in C#.

FeatureRecordClass
TypeReference type with value-based equalityReference type with reference-based equality
MutabilityImmutable by default (with init-only setters)Mutable by default
EqualityValue equality (compares data)Reference equality (compares object references)
Use caseData models, DTOs, immutable dataGeneral-purpose objects, mutable state
SyntaxConcise with positional parametersFlexible with constructors and fields
InheritanceSupports inheritance, but with restrictionsFull inheritance support
⚖️

Key Differences

Records are designed to represent data with an emphasis on immutability and value equality. When you create a record, the compiler automatically generates methods like Equals(), GetHashCode(), and ToString() based on the data members, so two records with the same data are considered equal. This makes records ideal for scenarios like data transfer objects or configuration settings.

In contrast, classes use reference equality by default, meaning two objects are equal only if they refer to the same instance. Classes are mutable by default, allowing you to change their state after creation. You must manually override equality methods if you want value-based equality.

Records also support concise syntax with positional parameters, making them quick to write and read. Classes offer more flexibility for complex behaviors, inheritance, and mutable state management, but require more boilerplate for equality and immutability.

⚖️

Code Comparison

Here is an example of a record in C# representing a person with immutable properties and value equality.

csharp
public record Person(string FirstName, string LastName);

class Program
{
    static void Main()
    {
        var person1 = new Person("Alice", "Smith");
        var person2 = new Person("Alice", "Smith");

        System.Console.WriteLine(person1 == person2); // True because of value equality
        System.Console.WriteLine(person1); // Prints: Person { FirstName = Alice, LastName = Smith }
    }
}
Output
True Person { FirstName = Alice, LastName = Smith }
↔️

Class Equivalent

The equivalent class version requires manual implementation of equality and is mutable by default.

csharp
public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }

    public Person(string firstName, string lastName)
    {
        FirstName = firstName;
        LastName = lastName;
    }

    public override bool Equals(object obj)
    {
        if (obj is not Person other) return false;
        return FirstName == other.FirstName && LastName == other.LastName;
    }

    public override int GetHashCode() => (FirstName, LastName).GetHashCode();

    public override string ToString() => $"Person {{ FirstName = {FirstName}, LastName = {LastName} }}";
}

class Program
{
    static void Main()
    {
        var person1 = new Person("Alice", "Smith");
        var person2 = new Person("Alice", "Smith");

        System.Console.WriteLine(person1.Equals(person2)); // True because of overridden Equals
        System.Console.WriteLine(person1); // Prints: Person { FirstName = Alice, LastName = Smith }
    }
}
Output
True Person { FirstName = Alice, LastName = Smith }
🎯

When to Use Which

Choose record when you want simple, immutable data containers with automatic value equality, such as for data transfer objects, configuration, or any data where identity is based on content.

Choose class when you need mutable objects, complex behavior, or full control over inheritance and lifecycle, such as for business logic, UI components, or entities with identity beyond data.

Key Takeaways

Records provide built-in value equality and immutability, ideal for data-focused types.
Classes are mutable by default and use reference equality unless overridden.
Use records for simple data containers and classes for complex, mutable objects.
Records have concise syntax and auto-generated methods, reducing boilerplate.
Classes offer more flexibility for behavior and inheritance scenarios.