This article describes the difference between value types and reference types and also shows how it is stored into the heap and stack.
One of the most misunderstood concepts in object oriented programming is the behavior of reference data types and how they differ from value data types. This article will attempt to clear a few myths and explain how they are stored in memory, how assignment operator works differently on them and how they are finally removed from memory.
Let’s first understand the basic differences between value types and reference types before we get into the concepts. The following will help you to understand it.
A reference type refers to an object which is created on the managed heap. In other words, the address of the object is stored in that reference variable. When a reference type is assigned to another reference type, only the reference is copied and not the value. The diagram below explains how reference types work when one object is assigned to other object. Both of them now refer to the same memory location.
In the diagram (D-1) obj1 and obj2 both refer to the same memory location. If a data member in the object is changed by using obj1, it is reflected by obj2 as well. Following are the reference types allowed in .NET.
Value types hold the actual value and are light weight types. They are allocated memory based on their scope.
• Global memory area – if value type is a global variable
• Stack – if value type is a local variable or method parameter
• Managed heap – if value type is a member of a class
Whenever a value type is assigned to the other value type, it is simply copied. Comparatively, the value type is better in performance, because the variable contains the object directly and there is no need of a reference. Following are the value types allowed in .NET.
The diagram (D-2) above explains how value types work when we assign one value to the other. The value of i, which is of integer type is assigned to another integer type with the name j. Both of them are allocated on the stack. Whenever a value type is assigned to another value type, the value gets copied.
The following example clearly demonstrates how value and reference types differ in behavior.
In the above screenshot, two integers i and j are created and assigned values. Changing the value of j does not change the value of i. On the other hand,when the reference variable obj1 is assigned to another reference variable obj2, they both refer to the same object, and hence contain the same values. Following is the output of the program.
Value types do not have the extra overhead of the garbage collector. On the other hand, reference types are stored on the managed heap and must be cleaned by the garbage collector. It’s better to declare a type as a value type in case the following mentioned cases are true.
If the type acts as a primitive type
Of other types will never be derived from that type
If the type will never be inherited from any other type
It’s also important to remember that reference types always hold the reference to an object and hence operators work differently on them.
An int is a value type, and a class is a reference type. How can int be derived from object?
int is not derived from object. When int is really used as int itself, then it is a value. If int is used as an object, then boxing is done. To justify, when int is used as an object, we are calling it as a reference to the object for which the memory is created on the heap. So here, ultimately the CLR converts the int value as reference to the object. The int is copied onto the heap and the instance of object is created.
static void Main(string args)
int x = 3; //New int value 3 is on the stack.
object obj = x; //new int on heap, set to value 3.
//Still have x = 3 on stack.
int y = int(obj);
2. C# 2008, Wrox Press
3. Bing Search Engine