Reference Types and the Ref Keyword visually explained

 
05 december 2008

One of the most common mistakes developers make when learning .NET is confusing Reference and Value Types with passing values by Reference or Value. In this article I will try to visually explain what the ref keyword does and what relation it has with referency types versus value types.

In C# there are value types (structs) and reference types (classes). This is one of the first things you learn when you start learning for the the .Net Foundations exam. For me it helped to visualize the way the system is set up. I will start very basic.

First of all you will need to understand the difference between a code reference and an actual in memory (value)object.

//code reference
Person p;

This will look like this:

//code reference which is attached to an actual in memory object
Person p = new Person(“Sjors Miltenburg”);

This will look like this:

One in memory object can have multiple references to it.

Person p = new Person(“Sjors Miltenburg”);
Person p2 = p;

This looks like this:

When you update a reference to an object the object will only stay in memory as long as there is still one reference “alive”.

//the object is NOT garbage collected
Person p = new Person(“Sjors Miltenburg”);

Person p2 = p;
p = null;

//the object is garbage collected
Person p = new Person(“Sjors Miltenburg”);
Person p2 = p;
p=null;
p2=null;

The Ref keyword is used when defining a method, but what does it do? To understand the use of the Ref keyword we first look at what happens to an object reference when it is used in a “normal” method.

public void ChangePerson(Person person){
//do something
}

//calling the method from somewhere else
Person p = new Person(“Sjors Miltenburg”);
ChangePerson(p);

This will look like this:

So we see that inside the method we get a NEW reference to the same object.
So if we were to do something inside the method like

person=null;

The reference “p” would still keep the object alive. Also reassigning the “person” reference to another object has no effect on reference “p” outside the method.

When we use the Ref keyword in the method we get the actual reference from outside the method.

public void ChangePerson(ref Person person){
//do something
}

//calling the method from somewhere else
Person p = new Person(“Sjors Miltenburg”);
ChangePerson(ref p);

This will look something like this:

So is this also possible for Value types? Value types behave different when you try to assign multiple references to them.

ValueType vt = new ValueType(3, 5, 6);
ValueType vt2 = vt;

This results in a copy of the in memory object with the new reference (vt2) attached to the copy:

The behaviour shown above is also valid for passing a ValueObject to a method without using the Ref keyword. Because of the ValueType’s behaviour (not allowing multiple references) you might expect that passing it to a method with the Ref keyword will result in an in memory copy of the ValueObject. However this is not the case.

public void ChangeValueType(ref ValueType vt2){
//do something
}

//calling the method from somewhere else
ValueType vt = new ValueType(3, 5, 6);
ChangeValueType(vt);

results in the following:

So this means that change a ValueObject inside the method will result in a changed ValueObject outside the method.

The picture above is an inaccurate visual representation, because the reference “vt2” does not reference another reference. A more accurate picture would probably be:

So what can we conclude from all this information:

The ref keyword is only used when you want to re-assign the reference to an object inside a method and want the references outside the method to be updated as well.


Werken met ?
Kijk dan bij onze mogelijkheden voor starters en/of ervaren IT'ers.


Categorieën: Development, .Net

Tags: , , , ,