From the course: C# Essential Training 1: Types and Control Flow

Understanding classes, structs, and records - C# Tutorial

From the course: C# Essential Training 1: Types and Control Flow

Understanding classes, structs, and records

- [Lecturer] When working in a typed language like C# where your variables have types, you're going to spend a lot of time creating and defining those types. So that's where we'll start here with the different ways you can define a type. That includes classes, struct, and records. Before I do a couple things here, I have all of these different types in one code file which isn't how you'd normally do that. I'm just doing it here to make it easy for us to see them all together. The other is you'll notice down here on line 12, I've got some squigglies under last name and on line 15 under first name. If I look at that, it's going to tell me that a non-nullable property must contain a non-null value when I exit a constructor. Now this is Visual Studio 2022 using .NET 6 and C# 10. And this is different if you're using a previous version. So this is a change that now enforces or provides some warnings around nullable reference types. We're going to talk about those a bit later. So for now I'm going to right click and edit my project file. I'm just going to come in here where it says nullable and I'm going to disable that. I can save that file, close it, and then those things will go away and it'll stop warning me about that. So I'm back now to the behavior you'd see before using Visual Studio 2022, before .NET 6, in case you're using something that's a little bit older. And I'll try and show you throughout the course things that have changed, the various versions of C#, and other tools that we use. What we've got here, starting on line three, is a standard interface for an IPerson. It's got four properties on it, first name, last name, ID, and age. And those are using the auto-implemented property syntax, which means we'll have that backing field created for us. I'm going to use that interface. We'll start by looking at classes. When you define something as a class, you're defining it as a reference type, meaning that a variable that points to an instance of this class is pointing at a reference or is a reference to that instance. So classes, as we can see, can implement an interface, the IPerson. I can also add other properties as I've done here, starting on line 18, to that class. So if I'm treating it as an IPerson, that's my variable type. Then I have access to those four properties from the interface. But if I'm working with it as an employee class, then I also have the additional properties there. And you can see starting on line 23, I have a manager class that derives from employee and can implement zero or more interfaces. I can only have one base class, but any number of interfaces. Those are reference types and those are probably the most common type used to date with C#. We also have structs or value types. I've defined a struct here called age. It's got properties, the date of birth and years old. And the difference here is this is a value type. Meaning if I have a reference, I have a reference to the actual object. And we'll see shortly, as we get into the ways that these different types behave, how that plays out when we're using variables, when we're copying, or passing things to and from methods. You can see on line 35, structs can also implement interfaces. So they can have properties, they can have methods much like a class. And then in C# 9, Microsoft introduced the notion of a record. So here I have a record called customer that implements IPerson. Looks very much like a class, and in fact, behaves in many ways like a class, but records are really intended for scenarios where you want to have immutable objects. They don't have to be immutable or unchangeable, but they can. And they're useful in scenarios where you're using it as maybe a data object. So you're passing it between service layers or between application layers, and it's primarily about creating an object with state and passing it around. You can see on line 51, records can have inheritance in this case. So I have a premiere customer that derives from customer and it adds the notion of a customer level. With C# 10, it was released in the fall of 2021 with .NET 6, we also have the notion of a record struct. So here we have an order that has an order ID and an order date, and that is going to have the behaviors of a value type, like a struct, but also the behaviors and the capabilities of a record. Now, if I come down to the recurring order and I try and derive from, say, order, because I want to just add some functionality to that, you'll start to see that it says the type order in the interface list is not an interface. Well, that's because that's how value types work. If I come back up to my vendor contact, for example, or my age, let's say, I want to do a new struct, say public struct, biological age. People like to talk about their biological age being different from their chronological age. And I'll say I want to derive from age. We're going to get that same warning because this is how value types work. They can implement interfaces, but they can't have a base class. They derive from value type. We'll just say, struct cannot inherit from base struct. Just so we keep that in there and I'll comment this out. So we've got it there. So when we're using structs or when we're using records structs, those same behaviors apply. What you might infer from that is that what this really means is we have record class. So again, in C# 9, that's all that's available is record class. In C# 10, you have both. And so you can specify, or if you leave out the second piece, then it defaults and assumes you have a class or reference type. Those are the basics of the three different ways you can define types, classes, structs, and records. And we'll see as we go forward, the different ways that they behave, so you can make decisions about what's the right way to define your type. Like I said, class has been most common up to this point. Record being newer is fast gaining a lot of traction with folks building microservices, building multi-layered applications, and using it for those immutable objects that they need to pass around.

Contents