Introducing C# 10: Record struct
Introduction
Last year with the release of C# 9, Microsoft introduced records. The record keyword gives a reference type new superpowers like immutability declared with positional records (or by using init-only properties), equality comparisons that mimic value types, and with-expressions that allows you to create a new record instance with the same property values, the properties you need to change. This drastically simplifies the process to copy objects.
This year, C# 10 brings records structs. They’ll carry a lot of the advantages of C# 9 records (which are reference types, like classes), but don’t get fooled: there are differences with structs because…. structs are different from classes!
In this article, we will see what a record struct is, and why a record class doesn’t behave like a record struct.
If you need a reminder on record class, you read this post:
https://anthonygiretti.com/2020/06/17/introducing-c-9-records/
This article has been made with my friend Dave Brock and I would like to take the opportunity to thanks him. I you wanna follow him you can find his post and his social medias infos: https://www.daveabrock.com/.
Syntax
First of all, Microsoft has made an improvement to record classes. With C# 9, to declare a record you replaced the “class” keyword with “record.” To avoid confusion when declaring structs as records, C# 10 allows a new syntax to declare a class as a record by mixing record and class keywords:
public record class Product {}
The C# 9 syntax remains valid:
public record Product {}
Declaring a struct as a record looks like this:
public record struct Product {}
It’s a more convenient approach to avoid confusion between a record class and a record struct. A record struct is a struct with all its struct properties and a record class is a class with all its class properties.
Immutability
Init-only properties are allowed on record structs:
If you try to reassign a property that has the init keyword set after its initialization you’ll get a compilation error:
Using positional records is quite different for record structs. Positional records on struct doesn’t make the record immutable as a record class. Because it’s a struct you have to set the readonly keyword to make the record struct immutable. The following code is equivalent to the previous declaration above:
With-expressions
Like a record class, a record struct allows the usage of with-expressions and works similarly to a record class:
Equality comparison
Because a record struct is a struct, comparing (with Equals method) two structs that have the same values will always return true. A struct is a value type, unlike a class. A regular struct doesn’t implement == and != operators, so it’s impossible to compare two structs with these operators. However, the comparison with these operators is allowed on a record struct:
Printing members
Record structs implement a new override of the ToString() method that allows printing a structured string of the struct record. With the same signature of Product struct, let’s compare the output:
If Product is a regular struct:
Id Product is a record struct:
Performance
In terms of performance, structs offer performance benefits. Using record structs is 20 times faster than a regular struct according to benchmarks.
You can find in this article a relevant benchmark: C# 10 – `record struct` Deep Dive & Performance Implications – nietras – Programming, mechanical sympathy, machine learning and .NET ❤.
Conclusion
This article aimed to introduce record struct with C# 10. Because it’s a big feature, probably the most in C# 10, I probably missed some aspects of record structs. At this time of writing C# 10 is still in preview, and this article may evolve once C# 10 is released.
Hope you’ll enjoy record structs, personally, I love it! 🙂