3 minute read

records are a new construct in C# 9. The idea comes from known working features from other languages. The promise of immutability and limiting “Spooky side effects at a distance” has me interested in replacing classes with Records!

So what is a record vs a class?

A record IS a class, with syntactic sugar on top. The record is more similar to a struct in practice, but it has the advantages of classes with regards to garbage collections and speed.

Why should I use records then? I already have “init” properties etc.

1. Records are Immutable (Unchangeable)

var nils = new MyRecord(Name: "Nils")
nils.name = "Not Nils" // <- This cannot happen.
// But we can create a new Nils
var newNils = nils with { name: "New Nils" }

You might think that this sounds like a hassle. But we are back to the spooky side effects to explain why its cool.

When I pass “nils” here to a method sendToVacation(nils) I can be certain that nils do not change, if the return type of sendToVacation is not a MyRecord.

2. Less Code for common stuff

You might say that I could do most of this before with classes and constructors.

public record MyRecord {
    public string Name { get; init; }
}
public class MyClass {
    public string Name { get; init; }
}

The MyRecord and MyClass above here might seem identical, but under the hood there are some changes already.

Records have built in

  • value equality (No more IEquatable!)
  • formatting for display (no more “.ToString()” -> Object in console)
  • syntax for nondestructive mutation.
    • You can copy a Record without any manual boilerplate.

3. Concise Syntax

The magic here is the “oneliner” to create records.

public record MyRecord(string Name); // Thats it

It even supports inheritance as a oneliner!

public record BaseRecord(int Id);
public record MyRecord(int Id, string Name) : BaseRecord(Id);

Attributes are also supported, so all backing fields have the same control as before

public record BaseRecord([property: JsonName("_id")] int Id);
public record MyRecord(int Id, [property: JsonName("name")] string Name) : BaseRecord(Id);

And I can extend the record with my own methods.

public record MyRecord(string Name){
  public int CalculateNumCharsInName(){
    return Name.length
  }
};

Cool!

There is much more to know about records, but this was a quick demonstration. Other advantages include great nullable support, but that will be in a later blog.

Thats all for this time.


Code Snippets are licensed under MIT No Attribution