|
Types in C# |
C# supports two kinds of types:
|
- Value Types : A value type is either a struct type or an enumeration type.A variable of a value type always contains a value of that type.Value types are stored on the stack.
Assignment to a variable of a value type creates a copy of the value being assigned.
C# provides a set of predefined struct types called the simple types. Examples of simple types include
- int
- double
- float
- boolean
- Enumerated Data Types(Enums) . We will discuss about enums and structs in our later
article.
- Struct types etc...
- Reference Types : Reference types store references to objects. Reference types include class types, interface types, delegate types, and array types.We will discuss about
each of these types in our later article.
Value types differ from reference types in that variables of the value types directly contain their data, whereas variables of the reference types store references to objects. With reference types, it is possible for two variables to reference the same object, and thus possible for operations on one variable to affect the object referenced by the other variable. With value types, the variables each have their own copy of the data, and it is not possible for operations on one to affect the other. Another important point to note is value types are stored on the stack, where
as reference types are stored on the heap. |
Lets understand the difference between value types and reference types with an example
|
|
using
System;
class
Class1
// Class1 is a reference type.
{
public
int Value = 0;
}
class
Test
{
static
void Main()
{
int val1, val2; // val1 and val2 are Value Types
val1 = 0;
// Inititalize val1 to 0
val2 = val1;
// Assign the value of val1 to val2.
Now val1 and val2, will have their own copy of value 0
val2 = 123;
// We assign 123 to val2. So the value
0 will be overwritten with 123, however val1 value will still be 0
Class1 ref1 = new
Class1(); // ref1 is an instance of class1.
Class1 ref2 = ref1; //we are setting ref2=ref1. Now
both ref1 and ref2 will be pointing to the same object.
ref2.Value = 123;
//Once we assign a value of 123 to ref2, even ref1 will contain
the same value as both
//the reference
variables are pointing to the same object.
Console.WriteLine("Values: {0}, {1}",
val1, val2);
Console.WriteLine("Refs: {0}, {1}",
ref1.Value, ref2.Value);
}
}
|
The output of the above program is shown below
- Values : 0, 123
- Refs : 123, 123
|
Figure 1 depicts how val1 and val2
value types are stored in memory
- Value types have their own storage locations in memory. In our example as val1 and val2 are simple types, they have their own storage locations.
- val1 = 0;
This statement will store 0 in the storage location of val1;
- val2=val1;
This statement will copy the value of val1 which is 0 into val2 storage location.
- val2=123;
This statement will overwrite 0 to 123 contained in val2 storage location. This will not impact the value contained by val1 as val1 has its own copy.
Note: Value types directly contain data in their storage locations. Hence operations on variable will not affect the
|

Figure 1 |
Variables of reference types store references to objects. With reference types, it is possible for two variables to reference the same object, and thus possible for operations on one variable to affect the object referenced by the other variable. The same is depicted in Figure 2 below.
- Reference variables are not objects by themselves they are pointers to objects.
- Class1 ref1 = new Class1();
This statement will create a ref1 variable that will be pointing to Class1 object. This object will have a value of 0 to which ref1 is pointing.
- Class1 ref2 = ref1;
This statement will create new reference variable ref2, and ref2 reference variable will be pointing to the same object as ref1. So bothe ref1 and ref2 will have a value of 0 and are pointing to the same object.
- ref2.Value = 123;
This statement is changing the value in the object pointed by ref2 to 123. Even ref1 is pointing to the same object. So now both ref1 and ref2 values become 123 as they are pointing to the same object.
|

Figure 2 |
Boxing and Unboxing : Type conversion
|
Value types can be converted to reference types and reference types can be converted to value types. This process is called boxing and unboxing.
- Boxing : Converting value types to reference types
- UnBoxing : Converting reference types to value types.
Example below illustrates boxing and unboxing.
Boxing and Unboxing in .NET is possible because of unified type
system. What this means is all types in .NET, directly or indirectly inherit from
System.Object type. As all types are inheritted from System.Object
we can type cast any type to System.Object. So inheritance is the key to type system
unification in .NET. We will discuss about inheritance in our later article. |
|
class
BoxingUnBoxing
{
public
static void Main()
{
int i = 123;
object o = i;
// Boxing
int j = (int)o;
// Unboxing
}
}
|
System.Object type has the following 4 methods defined. We will discuss about methods in our later article.
- Equals()
- GetType()
- GetHashCode()
- ToString()
As all types in .NET inherit directly or indirectly from System.Object type, every type will have these 4 methods. Figure 3 below depicts how .NET intellisense shows up the 4 methods on System.Object instance.
|

Figure 3 |
Is System.String a value type or reference type? |
System.String is a reference type. We have 2 types of strings in .NET
- Strings of type System.String. These strings are immutable which can affect the performance incase if we are doing intense string manipulations in our application.
- Strings of type System.Text.StringBuilder . These strings are mutable. If the application invloves intense string manipulations it is good practice to use
System.Text.StringBuilder class over System.String
|
|
Lets understand with an example what it means by strings of type System.String are
immutable. Below is an example depicting the same. |
|
using
System;
class
ImmutableStrings
{
public
static void Main()
{
string Text = "Hello";
Text = Text + " How are you? ";
Text = Text + "Where";
Text = Text + " are you from?";
Console.WriteLine(Text);
}
}
|
Explanation of what happens when each of the line in above program is executed
- string Text = "Hello";
This will create a reference variable Text pointing to a string object in memory.
- Text = Text + " How are you? ";
In this line we are appending " How are you?" to the string object pointed by Text reference variable. What we might think is that, the statement " How are you?" is appended to the word "Hello". In reality what happens is
- A new string object is created.
- The value "Hello" from the string object pointed by Text reference variable is copied into the new string object that is created in the previous step.
- The reference variable Text will now be pointing to this new string object. The string object which lost the reference will be present in the memory untill the grabage collector runs and cleans that string object which does not have valid reference variable pointing to it.
Note :
As string objects are not immediately destroyed after they have lost the reference and are destroyed only when the garbage collector runs, they are called immutable. This is not the case with strings of type System.Text.StringBuilder.
We will discuss about garbage collection in our later article. |
Difference between Value Types and Reference types in .NET
|
- Value Types are stored on the stack where as reference types are stored on the heap.
- Variables of the value types directly contain their data, whereas variables of reference types store references to objects.
- Value types differ from reference types in that variables of the value types directly contain their data, whereas variables of the reference types store references to objects.
|
|
Other related articles :
|
Njoy Programming
ByPrasad Cherukuri
|