Learn How To Program In C# Part 36 – Reference Types Vs Value Types


Hey, everybody. In this video, we’ll be talking about value
types versus reference types. One thing right off the bat that I want you
to know is that when you have a program that you wrote and you’re running it, the data
in that program is stored in memory. In C#, when you’re running your program,
there are two regions of memory storage. One is called stack and the other one is called
heap. Let’s talk about the stack first. The stack stores values of certain variables. It stores the program’s current execution
environment. It stores parameters passed into methods. That’s what it stores. But a stack is pretty much an array of memory
that acts as a LIFO structure. A LIFO is a last-in-first-out structure. A good analogy for it would be to imagine
a stack of papers. It’s a stack of papers, more specifically
a stack of reports. Let’s say your boss comes to you and he
says, “Listen, this is report #1.” And he puts it on the table. Then he puts report #2 on top of report #1
and says, “This is report #2.” And he goes on and on and on until he gets
all the way to report 30. He has report 30 all the way on the top. And then he tells you to go through all the
reports and do whatever you have to do. Normally, you would go from top all the way
to the bottom. So when you start processing, you would take
report #30, take it from the top, do whatever you have to do, then go to report #29, and
then 28, and then 27, and so on and so forth, until you get to report 1, and then finish
up with reports. That’s how the stack operates. That’s the analogy so you understand it
better. Another thing to understand is that all of
this is taken care of under the hood. You do not need to take care of any of this. Memory management is done under the hood for
you. All you need to do is understand it conceptually. You just want to understand how it works so
that you can work with value types versus reference types more efficiently. Another thing is that going back to the analogy,
remember how I said if the boss wants to put reports down on the table, when the boss puts
the report down on the table and then puts another report and then puts another report
and then puts another report, in the stack “language”, that would be called push. So when you want to put an item on the stack,
that is called pushing. When you are processing the reports, when
you’re taking things from the top of the stack, and you’re processing it and going
to the next one, that’s called popping. So deleting an item from the stack is called
popping. Now let’s talk about the heap. Heap is a chunk of memory space that uses
pointers to reference memory locations that are currently in use. That’s what a heap is. In .NET, there’s something called a garbage
collector. It goes around the heap and looks for any
heap objects that are not being used anymore and gets rid of them. And it does it under the hood. Memory management is done all for you. So you just need to know about it. That’s the stack and the heap. Why do we talk about stack and heap? Because they directly relate to value types
versus reference types. Let’s talk about the value types. The value types are always stored on the stack. Just so that we can make the example more
relatable, some of the value types are int, double, decimal, enum, bool. Let me write this down. bool a=true;
It’s just a simple variable declaration. This is a value type. This would be stored on the stack. That’s just an example so I can make it
more relatable for you. The reference types are stored not just in
one but in two regions of memory. First one is the heap and the second one is
the stack. On the heap, for the reference types, you
store the actual value. The actual data of the reference type is stored
on the heap. But on the stack, you save the memory location. The address of where the value stored on the
heap, you save that on the stack. Basically, the stack knows how to point to
the heap for the actual data. So that’s very, very important to know because
when it comes to passing and assigning values, this is very, very crucial. Just on this example, let’s create another
method. static void Main(string[] args)
{ bool a=true;
MakeItFalse(a); Console.WriteLine(a);
} static void MakeItFalse(bool a)
{ a=false;
} You take a and pass it as a parameter to the
MakeItFalse() method. Then you print a. What do you think is going to happen? Do you think a will be false when you print
it? Let’s see. The output is:
True Wow! Look at that. It’s still true. Why? Because when you are dealing with value types,
when you are assigning or passing value types as parameters, you’re actually making a
copy of them instead of having the same thing go through and come back. So the parameter a of the MakeItFalse() method
is a different one. It’s a copy of the variable a of Main. It just has the same value, but it’s a different
copy of it. So then when it comes back up, remember the
reports, report 1, report 2? So in the stack, Main() is report 1, MakeItFalse()
is report 2. You process the report 2, comes back to report
1. But the scope of report 2 now is gone. Report 1 has no idea about report 2 or what
the a was. It has its own scope of a which is true. So it stays as true. It doesn’t matter if you changed it in the
other one. It’s already gone. Now let’s see how the reference type behaves. I’ve created a class called Person. It has Firstname and Lastname on it. class Person
{ public string Firstname { get; set; }
public string Lastname { get; set; } }
static void Main(string[] args) {
Person person1=new Person(); person1.Firstname=“John”;
person1.Lastname=“Smith”; Person person2=person1;
Person person3=person2; Person person4=person3;
Person person5=person4; Console.WriteLine(person5.Firstname);
Console.WriteLine(person5.Lastname); }
We create a Person object in Main called person1. We name it “John Smith”. Then we create four other Person objects. Let’s see what we get for person5.Firstname
and person5.Lastname. Let’s run the program. The output is:
John Smith
Why? Because when you created the person1 object
and assigned it Firstname and Lastname, the actual value of this was stored on the heap,
but the address of it was stored on the stack. And then when you assigned person1 to person2,
you assigned the address. So person2 now is pointing to the same thing. And then you did the same thing with person3,
so it’s pointing to the same thing. person4 is pointing to the same thing. person5 is pointing to the same thing. Here’s the interesting part. What happens if we do this?
class Person {
public string Firstname { get; set; } public string Lastname { get; set; } }
static void Main(string[] args) {
Person person1=new Person(); person1.Firstname=“John”;
person1.Lastname=“Smith”; Person person2=person1;
Person person3=person2; Person person4=person3;
Person person5=person4; person5.Firstname=“Jane”;
person5.Lastname=“Smithh”; Console.WriteLine(person1.Firstname);
Console.WriteLine(person1.Lastname); Console.WriteLine(person2.Firstname);
Console.WriteLine(person2.Lastname); Console.WriteLine(person3.Firstname);
Console.WriteLine(person3.Lastname); }
Before we even make a prediction, let me show you what the first example did. At the end all five Person objects started
to point to the same object. So what do you think is going to happen when
we change person5? They’re all pointing to the same object. I print out the Firstname and Lastname of
person1, person2, and person3. What
do you think all of these values are going to be? Will they still be “John Smith”? Look at this picture again. All of them are pointing to the same Person
object. But on person5, we’re changing this. What do you think 1, 2, and 3 will be? Let’s check it out. The output is:
Jane Smithh
Jane Smithh
Jane Smithh
The Firstname and Lastname were replaced. Why? Because they are all pointing towards the
same object. And if you change this, you affect all of
the ones that point to the actual value. And that is the key when you are dealing with
reference types. Now let’s see how this would behave if we
did the similar example as we did with the value types. static void Main(string[] args)
{ Person person1=new Person();
person1.Firstname=“John”; person1.Lastname=“Smith”; ChangeFirstName(person1); Console.WriteLine(person1.Firstname);
Console.WriteLine(person1.Lastname); } static void ChangeFirstName(Person person)
{ person.Firstname=“Avetis”;
} We have a method ChangeFirstName() that changes
the Firstname of the Person object passed to it as parameter. What do you think is going to happen in this
case? Before, we did the value type. And we set the thing to false. The actual value in our Main method did not
change when we printed it. Why? Because it was saved on the stack. So what happened was once it was popped, the
scope was destroyed, and the Main had its own scope, so it used that value. In this case, let’s see what happens. The output of the program is:
Avetis Smith
So it did change. This is interesting. What happened was we had person1. The person1 was created. Then we
passed that down the ChangeFirstName() method. There was another Person object created on
the stack. And ChangeFirstName() had the pointer. What we did is by passing in the person1,
we didn’t pass in a copy of the Person object. Instead, we passed in the address of the Person
object. So the ChangeFirstName() method took that
address and it referred to the object in heap. It changed “John” to “Avetis”. And once it was gone, once it was popped, person1 was still pointing towards the same
Person object, which was changed by the method that it was calling. The Person object was already changed because
it wasn’t a copy. It was passed by reference. It wasn’t passed by value. I hope that makes sense. This is very, very important to know. If you like this video, please give it a thumbs
up. I would really appreciate. Don’t forget to subscribe. And if you have any questions, please leave
them down below. Thank you for watching.

3 Replies to “Learn How To Program In C# Part 36 – Reference Types Vs Value Types”

  1. Quick Question, why do you use static before the method?

    I understand why but does it matter in this example or can this be anything. Can you do for example Public void ChangeFirstName() or are you using static for a reason.

Leave a Reply

Your email address will not be published. Required fields are marked *