Introduction
In this article, I will discuss about the value types and reference types in C# which are of course the basic building blocks of programming. These are the two main important pillars of programming in .NET Framework, as object oriented programming starts with creation of classes or structs and their variables which we can further use to achieve our programming tasks in C#. First, I would like to discuss about the Reference type and then Value type in this article.CodeProject
Reference Types
Following are the points which we need to know about reference types:
- Reference types are always allocated the space on the managed heap. You can read about managed heap and stack here.
- As soon as we create a variable of reference type and assign it some reference, a space is allocated on the managed heap after calculating the amount of bytes the data members and member variables are required to take.
- All the classes are reference types.
- The
new
keyword is used to create a reference type. It basically returns the address of the memory location for the reference type where it is created on heap. For example, I have created a class which is a reference type:
public class MyReferenceType
{
public int myVar;
}
And I can create an instance of this type as follows:
MyReferenceType refType = new MyReferenceType();
refType.myVar = 5;
Console.WriteLine(refType.myVar);
MyReferenceType copyRefType = refType;
copyRefType = refType;
copyRefType.myVar = 10;
Console.WriteLine(refType.myVar); Console.WriteLine(copyRefType.myVar);
Console.Read();
refType
is a variable of type MyReferenceType
which is stored on thread stack memory, but it contains a reference to the memory location on the heap.
In part two of the above program, I have copied the reference contained by the myVar
variable to the copyRefType
variable which is another variable of the same type. In this case, only the reference is copied not the whole value as we can see in the figure 2. Both of these variables are basically pointing to the same memory location. Now when I change the value of myVar
for the newly created variable copyRefType
it changes the value for the previous variable, i.e., refType
.
- Following are the points which we should need to know to understand, why it could be costlier to create reference types:
- Whenever a reference type is created, a reference on the heap memory is created.
- As soon as heap memory comes into the coding, garbage collector has to take part to clear the references, which can be a costly operation.
- Along with the usual memory location of the reference type, additional memory overhead is required to create more fields, which are internal to the .NET runtime. These fields are basically used to get the lock state for multithreading and a flag to indicate whether the object has been fixed by garbage collector.
Value Types
In this next section, I want to discuss about the Value types:
- As we can learn from my previous discussion of the reference types, there are some drawbacks which we need to understand while dealing with them. To nullify these effects, value types were introduced. These are more frequently used types and are used when we can’t afford to take extra memory pressure for more frequently used types.
- Value type instances are usually allocated on threads stack but they can be contained as fields in reference types.
- There is no need to access the memory space each and every time when we are changing or assigning the value to value types. In programming context, we can say that there is no need to dereference the pointer when manipulating fields which is the case with reference types.
- Since value types are allocated on threads stack memory and this is a volatile memory as whenever the scope is outside of memory location, it is cleared automatically. There is no need to call GC to get the memory cleared which reduces pressure on memory.
Struct
s and Enum
s are user defined value types.
- Value types are derived from
System.ValueType
which itself is derived from System.Object
type.
- Value type cannot inherit from other value type or reference type but can inherit from Interfaces.
- Value types are sealed, i.e., no other type can inherit from them.
- Let's check a code example. I have created a value type (
Struct
) as shown below:
public struct MyValueType
{
public int myVar;
}
And I am assigning the values to myVar
variable as shown below:
MyValueType valType = new MyValueType();
valType.myVar = 5;
Console.WriteLine(valType.myVar);
MyValueType anotherValType = valType;
anotherValType.myVar = 10;
Console.WriteLine(valType.myVar); Console.WriteLine(anotherValType.myVar);
Console.Read();
Please have a look at the following figure while I explain what is happening. For clarity, I have merged this scenario with the previous one of reference types.
Value type memory allocation in C#
Value type
I have created a variable of MyValueType
as valType
, which is stored on the stack memory. I have assigned a value to myVar
of valType
variable a value of 5
. Again, I have created a new variable of MyValueType
as anotherValueType
as copied it the values of valType
variable. While we do this, a different space is arranged for anotherValType
in stack’s memory unlike reference types which copy the reference.
As we can see from the above code, even if we change the anotherValType.myVar = 10
, the valType.MyVar
remains unchanged, it is because a new memory was allocated for anotherValType
in thread’s stack which you can see in the figure.
We should use Value Types only
- If it is a simple type and no member function modifies its instance fields
- If there is no need to derive from other types or being derived to other types
- If instances of methods are small
This was all about the reference type and value type in C#. I hope I have made the understanding of these two things quite simple and verbose for you.
Please let me know your thoughts about the article.
Going further, you can learn about the type safety in .NET here and type conversion in .NET here.
The post Value type and Reference type Explained appeared first on Dot Net For All.