Bald Bearded Builder
csharp/what-is-the-record-type-in-csharp

What is the Record Type in C#?

Returning `Task` instead of `async void` keeps asynchronous work observable, testable, awaitable, and able to propagate exceptions correctly.

Loads from YouTube when you press play

Transcript 4 topics

Prefer records over classes

0:00

You got a class, you got a struct, maybe this should be a record. So a record is a reference type just like a class by default. Now you could have a record struct, which is a value type and allocated on the stack. We'll get into that a little bit later. One of the sweet things about records is this nice new syntax for creating them.

Check this out. Don't worry if that feels icky because you can still use that old syntax of putting the properties inside the body explicitly. One common misconception I see with records is that people think they're immutable always and that's not the case. Now if you use that concise syntax, they are immutable by default for classes but not for structs.

Understand record immutability

0:37

And then if you use the full body syntax, you need to actually specify that it's a GET and knit. Why does that work for the short syntax? Well, because Microsoft defaults it to creating those properties as GET and NITs when you use that concise syntax. If you look at this class, can see it's it's still a record but we've specified SET on the properties which makes them mutable. So yeah, by default in that small syntax, it's gonna try and make it immutable for you but there are ways to override that and you need to be aware of what you're doing.

What's the benefits of using a record class? Well, unlike structs, they do still support inheritance like normal classes. Another nice feature is the ability to keep your immutability but also be able to copy objects using the with keyword. Now don't get diarrhea of using the with keyword.

That's kind of a code smell if you're copying objects like that all the time. One of the coolest features to me though is the built into string or print members functionality.

Use equality and deconstruction

1:39

When you normally print out a class, you're going to get the class type but in the case of a record, you're going to get the type but also the properties and their values. That is just chef's kiss. Not to mention the amazing equality checks. Again, when you normally compare two classes using some kind of equality check, unless you like overrode the default, you're gonna get a comparison in the references. Does this reference match this reference?

But with record classes, they're not checking equality of the reference, they're actually checking equality of the properties and values. Deconstruction is also a really nice built in feature. Of course, you could write that into your class yourself but it's really nice to have it baked in so that if you need to pull properties out, you just use it. And don't worry, if you don't want to see some properties go out deconstructed, just use the override to change that functionality and and hide what you want. In fact, all of these functions are overridable.

Wanna change that awesome print or two string functionality? Go ahead. The world is your oyster. Override it. Wanna modify how that copy works?

It's okay. Just overwrite it. And like I mentioned about the deconstruct method, you're sensing a theme here? If you don't like it, just overwrite it. Yeah.

You get it. So when should you use them? Well, certainly data transfer objects are an obvious choice.

Use records for DTOs

2:54

If you've got data coming in or out of an API or through an HTTP request, Obvious choices for this where you don't need to mutate the data that's coming in or out. Is there data from your database that you never change? Perhaps time zones or countries and their country codes? Good choices. But an obvious reason why you wouldn't want to use a record class is if you want to change the data.

Things like POCOs, things going in and out of your database that you may need to edit, bad choices there. Now that covers record classes, but let's talk about record structs for a minute. They set up very similarly. The same kind of syntax, only you need to specify struct in this case. One huge difference that you need to remember though is that by default using that concise syntax, they don't default to being immutable.

They're actually created as GET SET accessor methods. So if you want that object to be immutable, you need to use the longer form of the struct syntax and specify the properties with GET INIT or GET PRIVATE SET, however you want do it. One crazy cool fact about record structs is that unlike regular structs, they don't use reflection which makes them insanely faster than regular structs. In fact, I would even say, if you don't have a reason to use a regular struct, you should just use record structs from here on out. The record keyword has been around for a while and I'm really interested if your team has adopted it yet.

Let me know in the comments below how it's gone for you. Until next time.

Sign in to join in. Reading needs nothing.