C# 9 records are worth a look

Posted: (EET/GMT+2)

 

As .NET 5 gets closer, one of the more interesting C# 9 features is the new record type. For an overview about C# 9, see here.

Records are useful when you need to model data with less boilerplate than a normal class. For example, a small customer model can be written like this:

public record Customer(int Id, string Name);

This gives you a type with value-based equality, a readable string representation, and a compact constructor syntax.

For example:

Customer first = new Customer(1, "Ada");

Customer second = new Customer(1, "Ada");

Console.WriteLine(first == second);
Console.WriteLine(first);

The values compare as equal because records compare by value instead of only by object reference (like classes would).

Records also work nicely with non-destructive updates using the with expression:

Customer original = new Customer(1, "Ada");

Customer updated = original with { Name = "Ada Lovelace" };

The original value remains unchanged, and the updated variable receives a copy with the modified property.

A simple rule: records are a good fit for data transfer objects, messages, configuration values, and small immutable models. But, they are not a replacement for every class. If the object has complex behavior, identity, lifetime, or internal mutable state, a normal class may still be clearer.

A more explicit record can also be written with properties:

public record Product
{
    public int Id { get; init; }
    public string Name { get; init; } = "";
    public decimal Price { get; init; }
}

The init setter allows properties to be assigned during initialization, but not changed later in normal code.

Records make the intent visible. If the type is mostly data, use a record. If the type is mostly behavior, use a class.

Hope this helps!