C#  

What are C# Record Types and When to Use Them?

Introduction

In modern C# development, record types have become a powerful feature for writing clean, readable, and maintainable code. Introduced in C# 9, records are mainly used for storing data in an immutable way.

If you have worked with classes before, you might wonder why record types were introduced. The answer is simple: records are designed for scenarios where you want to represent data, not behavior.

In this article, we will understand what C# record types are, how they work, and when you should use them in real-world applications.

What is a Record Type in C#?

A record is a special type in C# that is used to define immutable data models.

Unlike classes, records are value-based, meaning they compare objects based on their data rather than memory reference.

Key Features of Record Types

  • Immutable by default

  • Value-based equality

  • Built-in support for cloning

  • Cleaner and shorter syntax

  • Ideal for data models

Example of a Record

public record Person(string Name, int Age);

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

        Console.WriteLine(person1 == person2); // True
    }
}

Here, both objects are considered equal because their values are the same.

Record vs Class in C#

FeatureClassRecord
EqualityReference-basedValue-based
MutabilityMutable by defaultImmutable by default
Use CaseBehavior + DataData-focused
SyntaxMore verboseConcise

How Record Types Work Internally

When you create a record:

  • The compiler generates methods like Equals(), GetHashCode(), and ToString()

  • It creates value-based comparison logic

  • It supports non-destructive mutation using 'with' keyword

This reduces boilerplate code and improves readability.

Immutable Nature of Records

By default, records are immutable, meaning their values cannot be changed after creation.

public record Person(string Name, int Age);

var person = new Person("John", 30);
// person.Name = "Mike"; // Not allowed

This helps in building safer and predictable applications.

Using 'with' Expression in Records

Records support cloning with modification using the 'with' keyword.

var person1 = new Person("John", 30);
var person2 = person1 with { Age = 35 };

Console.WriteLine(person2);

This creates a new object instead of modifying the existing one.

Types of Records in C#

1. Positional Records

Defined using a compact syntax:

public record Person(string Name, int Age);

2. Non-Positional Records

Defined like classes:

public record Person
{
    public string Name { get; init; }
    public int Age { get; init; }
}

3. Record Structs (C# 10+)

Records can also be value types:

public record struct Point(int X, int Y);

When to Use Record Types in C#

1. Data Transfer Objects (DTOs)

Records are perfect for DTOs where you only need to transfer data between layers.

2. Immutable Data Models

Use records when your data should not change after creation.

3. Value-Based Comparisons

If you need equality based on values, records are the best choice.

4. API Responses

Records are commonly used in Web APIs for request and response models.

5. Functional Programming Style

Records support immutability, which is important in functional programming.

When NOT to Use Records

  • When you need mutable objects

  • When behavior is more important than data

  • When performance is critical and struct is a better fit

Real-World Example

Let’s consider an API response model:

public record ApiResponse(string Status, string Message);

var response1 = new ApiResponse("Success", "Data loaded");
var response2 = new ApiResponse("Success", "Data loaded");

Console.WriteLine(response1 == response2); // True

This makes records ideal for backend and API development.

Advantages of Record Types

  • Less boilerplate code

  • Built-in equality comparison

  • Safer with immutability

  • Better readability

Common Mistakes Developers Make

  • Using records for complex business logic

  • Assuming records are always immutable (can be changed with init or mutable properties)

  • Not understanding value-based equality

Best Practices

  • Use records for data-only objects

  • Keep records small and focused

  • Prefer positional records for simple use cases

  • Avoid mixing business logic inside records

Summary

C# record types are a modern and powerful feature designed for data-centric programming. They provide value-based equality, immutability, and a clean syntax, making them ideal for DTOs, API models, and functional-style programming. By understanding when to use records and when not to, you can write cleaner, more efficient, and maintainable C# applications.