C# and .NET Basics

Types

Spencer Schneidenbach

Spencer Schneidenbach

Aviron Software, Microsoft MVP
C# and .NET Basics

Check out a free preview of the full C# and .NET Basics course

The "Types" Lesson is part of the full, C# and .NET Basics course featured in this preview video. Here's what you'd learn in this lesson:

Spencer explains the differences between value types and reference types. He also explains the concept of nullability and how reference types can have a value of null, which can lead to null reference exceptions. He briefly mentions the concept of boxing and unboxing, which involves converting a value type to a reference type and vice versa.

Preview
Close

Transcript from the "Types" Lesson

[00:00:00]
>> Spencer Schneidenbach: So let's talk about types. So I want to talk about a couple of different, the types of types that are available that has value and reference. The core thing that I kind of want to emphasize is the how these things get passed between methods. So I'm going to go ahead and format this nicely.

[00:00:25]
I'm going to declare this person type. Don't worry too much about the syntax right now. It's just a way of defining a person, a with a name and an age, and you can see that we instantiate it here and that we change the age. So a value type property that is really important to understand is that when you pass in that age, it's passing in a copy of that value.

[00:00:48]
It is not passing in the actual value itself. So if we check this and we go down, you can see that 20 is the value of the age. So if we do console dot write line, person dot age. Age has not changed. Play, we'll run it, and you can see that person.age has not changed.

[00:01:06]
And that's because value types, they're on a, first of all, they're on a much faster space of memory. They're collected, they are, they are deallocated or removed from memory as soon as they're removed from scope. And they're considered to be on what's on the stack, so they're a lot faster to access.

[00:01:24]
Those are the properties of value types. The most important part to note in this is that copies of value types are passed around typically to methods. You can refer to them by reference. In most business programming, in most programming I've done, I've not done that, but in certain high performance situations, that can be useful.

[00:01:45]
The important thing to note is that value types simply just are passed around by copy. So, you see that even though we've changed this value of age to 10, it does not affect our person class, whereas a reference type does not have that same kind of protection. So let's take this, this example, into it, and use this as our example, boom, boom.

[00:02:10]
So you can see that we still have a person, we have old name, and then we're gonna change their name. So I'm gonna write that out this, because it's what we refer to as an instance of a class. So this is a person, this is a real walking person, or at least a representation of one.

[00:02:28]
We're gonna change their name, and what we're gonna do is we're gonna pass in this person reference. So a reference type is a variable that points to a certain location in memory. It doesn't actually have an actual copy of the value. That's mostly important for the purposes of understanding kind of how reference types are treated, mainly in terms of the ability to change values on them.

[00:02:50]
But you can see that because it's a reference type and not a value type, as soon as we change Person.Names name to New Name, that's what's printed to the console. This person is now their name is now changed, and that's really the most important piece, semantic difference, or day to day difference, that I want you to absorb.

[00:03:08]
When we're talking about value types versus reference types, it's mainly as they're passed around, how they're treated. And reference types are essentially mutable, they're not passed by value, they're not made, we don't make a copy of this person. The actual person is given to the change name method.

[00:03:29]
>> Spencer Schneidenbach: I did touch on stack versus heap. Not super necessary to know this in depth for the purposes of this course, but it is certainly there if you wanna refer to it. The important thing to note is that reference- Types because they're stored on the heap and they are not deallocated right away.

[00:03:43]
As soon as they leave scope, they are actually deallocated by the garbage collector, which is the process that the CLR uses to clear up memory. The difference between those things for the purposes of this course isn't super, super important. Just know that value types are deallocated very quickly, whereas reference types may not be deallocated right away.

[00:04:05]
And that really makes a difference when you're talking about a large amount of objects in memory. Okay, so as long as we're talking about value types and reference types, we talked about kind of default values for value types, right? So we can actually set using this keyword, we'll call it a, and we can say the default type for a and the default type is basically given a value type or a reference type.

[00:04:31]
What is the quote unquote default value. For a value like int, it's gonna be 0. For float, it's gonna be 0 Boolean, it's gonna be false and so on. But reference types are different because they have to deal with null. So this is a really fun part of the .NET runtime and a source of frustration for many developers.

[00:04:51]
So if you're of if you're a developer and you've experienced an error like this and you're in good company because value reference types can have what's called be what's called null, and null is is complete absence of a value. To the point of if you try to access or use a reference type that does not have a value, if we change this to null and we run this, we are going to get a runtime error and.

[00:05:19]
You'll see that the runtime error is indeed null reference exception, which I've touched on as being the most common and probably the most frustrating for new and senior developers and .NET alike. This is not specifically just a .NET thing. There's the same thing happens in JavaScript, right? When you get the error it's something that's like you can't make a function call on an empty object, it's essentially the same thing.

[00:05:48]
So nullability is kind of an important thing to understand and embrace when you're talking about because most of the types that you're gonna be working with in programming are going to be a reference type of some kind. So it's important to understand the implications of null. Now, recently, Microsoft has added features to the language and and to later versions of NET to handle this more gracefully for new projects.

[00:06:15]
You can actually turn on what's called Explicit like nullability and turn it on, turn on explicit like nullable handling. Reference types in most code bases, especially older ones are gonna be treated as a person like this is going to be treated as I can be null or I cannot be null, it's one of the two.

[00:06:38]
If you have nullability turned on, you can, if you have nullability turned on, you can treat those as explicitly saying like, okay, I explicitly want the, to mark this class as being null. So let me show you kind of what that looks like. So we haven't talked about null, nullable types, but there are ways to set an int, for instance, to a null, and that is a nullableInt = null.

[00:07:07]
So this question mark basically says that is a variable that can or cannot have a value. What are the implications of that? Well, nullable is a special class that has two properties on it. It has value and it has value and it has value is a Boolean to say, does this nullable structure have a value?

[00:07:29]
And if it does, then you can access it with value. And if it doesn't, if you try to access the value, it will throw a runtime error. And we can see that here, nullableInt.value. You can see that if we run this. That you see that we get an invalid operation exception because nullable object must have a value and you can see that we've set it to not nullable.

[00:07:54]
So this has been a feature for a long time in .NET and only recently the last few years. Do they add this feature for of this nullable feature to reference types as well. Such that you can say, in a method, for instance, you can say this person might be null, to which it would turn around and warn you, hey, you might be dealing with the null reference here.

[00:08:19]
So you can ask the little you can ask the little thing to say, well, what should i What should I do to which case, if you're using a brow, right, an ID, like writer, it will suggest fixes for you. Sometimes this there are, there are fixes to which .NET just does, wants to warn you, but the IDE doesn't have a fix for you in line.

[00:08:43]
So the way to do that is to check to see if it's null first, person does not equal null. And you can see that, put that in some curly braces and you can see that now we have person.name, we've safely checked it, and c sharp's compiler stops complaining at us What is a use case for having a nullable integer?

[00:09:04]
A nullable integer. Let's say that you're working in a database, and you're holding a database of people, and two of the required fields are first name and last name, but you don't require age as a field for creating that user. You would put the value in that database as just being null.

[00:09:29]
But then later down the line, now you could say, well, I wanna set this age or date of birth is another field that can be nullable, so, great question.
>> Spencer Schneidenbach: I do want to mention boxing and unboxing only because it's slightly important just in kind of understanding how reference types and value types operate.

[00:09:53]
And I touched on this earlier, but if you assign the value of an int, like this number here to a value that is typed object, this will be converted to a value, to a reference type, it's referred to as boxing. And boxing has some unique characteristics, this thing will now get stored on the heap and not the stack.

[00:10:10]
And it's really only important to know as a thing that happens at the runtime, at the runtime level. Most of the time in programming, you're able to kind of just ignore this and most of the time, you're not declaring ints inside of an object and then unboxing them later, but essentially, it's converting back and forth from a value to a reference type.

[00:10:30]
Again, this is not super important for most day to day programming, but it is a thing to know, yes, Mark,
>> Student: Could you get buffer overflow when using a null Integer?
>> Spencer Schneidenbach: Can you use a buffer overflow getting if you use a null integer? I don't know. I don't know about a buffer overflow.

[00:10:51]
But if you're typically, if you're trying to access the value of a nullable integer and it is null, then what you'll get is invalid operation, exception. And you can see that if you navigate into the nullable code, you can see that the value here is if it does not have a value, then it's going to throw the invalid operation exception that says that nullable object must have a value.

[00:11:15]
>> Spencer Schneidenbach: It's pretty much the only exception that I know that you're going to encounter when you're dealing with a nullable value type.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now