For the record, C# is now more functional
By: William Ploger
Tags: Programming, Software Development, Dotnet, Dotnet Core

Photo by Max Duzij on Unsplash

C# 9.0 adds new reference type and Init Only Setters

With C# 9.0, Microsoft has introduced a new reference type called Record Types. F# and other functional developers will see this concept as something inherit to functional programming, but this will be a bit new to most C# object programmers. This can be really handy if you want to pass data around, but don’t want to change the state of that data and only want to take some action or calculations on that data. By making it immutable, you have a certain guarantee that some change in state of your data won’t cause an issue or exception downstream. In fact, if you are going to make changes to the state of the record object, one would need to make a copy of that object instead of changing its state. Think of a Record type as DATA and not an OBJECT here.

Another aspect of Records is that they also support inheritance, just like normal classes. In this way you can create different types of records based on a super record and using the object as a classic object orientated type. In addition, when creating a record type, it comes with methods for testing equality automatically. You could create a C# class from scratch doing everything a Record does, but a Record object adds a lot of functionality that you won’t have to build. It’s interesting to note here, that with Records being reference types and classes underneath, it means that they live on the heap, and so are targeted for garbage collection just like classes.

The Init Only Setters are also something new in C#9.0, and we can see them in action in the struct example below:

The Init portion of the property allow the fields to be set at object construction time, but after that, the fields are no longer settable and thus are now immutable. Here we get an immutable struct, which can also be handy. In addition, you can mix and match these. Some fields can be immutable and other don’t have to be. This, of course, works the same in classes as a record is really just a class with Init only setters and some equality methods.

So why not just create immutable structs you ask? Well, for one, structs are value types in C# and thus will live on the memory stack and if you have large or long living structs this can lead to performance issues or a stack overflow. Keep one’s structs in C# small and short lived. If you are passing data around your application, this data may be long lived. This does mean that your record objects will be slower to be accessed from memory than structs because they sit on the heap.

In summary here are some keys to what makes a Record special:

SIMPLE construct using an IMMUTABLE data structure by default. Robust equality support. This allows you to compare the VALUE of one Record to another. Simple Constructor and De-constructor support.

And again, C# gets some functional programming features that it has been accumulating for years now moving it into both an object orientated and functional programming language. I have been concentrating on Python and Swift for the past couple of years and coming back to focus on C# has been an eye opener to just how far this language has come over the years and I still love coding in it. You can see some of my example code for Records at github.