On this blog I regularly publish articles with tips and tricks for the programming language C# .Net.
C# is a modern, object-oriented programming language, which fully ultilizes the possibilites of the .Net framework. I also write about app programming for Android via C#, as well as PHP and Matlab. The difficulty of this blog is supposed to be variable, I hope for beginners and experts there is always something to look for.
If you have questions or suggestions, I am happy about your emails.

Friday, September 3, 2010

Difference Between Value Types and Reference Types

In C# there are, like in many programming languages, basically 2 datatype variants: There are value types and reference types.
Variables, which base on value types, save the actual value of the variable. In contrast to that, variables which base upon reference types, only save a reference to the memory address of the variable.
Another difference between these types is: Value types are saved in the stack, reference types in the heap.
If you copy a value type, the value gets copied, after that exist 2 variables with the same value. If you copy the value of a reference type though, only the reference is copied, afterwards there are 2 references point on the same value in the heap. So if you change the value of the original reference variable, you also change the value of the copied reference variable, as they point to the same memory address.
The most datatypes in C# are value types, as for example byte, int and char. Reference types are generally only classes and arrays.

So why do we need to know all this when programming?
Most essential is this knowledge, when calling functions with parameters.
The following easy example should illustrate this:

There are 2 functions, ResultValue() and ResultReference(), which are called from Form_Load().
The first expects 2 variables of the type integer as parameter, which are the numbers 8 and 3. In the first function the first given number (8) is divided by 2 and the product of both numbers (4 * 3 = 12) is returned.
In the second function ResultReference() also the first number of the array is divided by 2 and the product returned (4 * 3 = 12).
However, the integer parameters of the first method are value types, so when handing them over to ResultValue(), a copy of them is created in the memory. The division is only done with the copy, the original number NumberA still is 8 after returning from the function.
The array given to ResultReference() is a reference type, when handing the parameter over to the function only the reference is copied, the variable still points to the same memory address in the heap. If the first number of the array is divided by 2, after returning from the function also the original number in the array is 4.

To change this behaviour, there is the keyword ref. If this is put in front of the value type parameter, this is created as a reference type parameter, when handing it over to the function, no value copy is created, but the reference to the original value:

// value typesint NumberA = 8;int NumberB = 3;

int NumberC = ResultValue(ref NumberA, ref NumberB);

In the above example then the original variable, NumberA, is divided by 2.
To convert value types to reference types there is no corresponding keyword, when handing over the parameters manually a true copy of the object, a deep copy, has to be created.