Saturday, January 22, 2011

C # : Difference between Value Type and Reference Type

what is a reference type?

In .NET or in particular in C# there are two main sorts of type: reference types and value types.There is generally a lot of confusion between these two types. Here's a quick explanation:
A reference type is a type which has as its value a reference to the appropriate data rather than the data itself. For instance, consider the following code:
StringBuilder strb1 = new StringBuilder();
 
 Here, we declare a variable strb1, create a new StringBuilder object, and assign to strb1 a reference to the object. The value of strb1 is not the object itself, it's the reference. Assignment involving reference types is simple - the value which is assigned is the value of the expression/variable - i.e. the reference. This is demonstrated further in this example:
StringBuilder strb2 = new StringBuilder();
StringBuilder strb3 = strb2;
 
Here we declare a variable strb2, create a new StringBuilder object, and assign to strb1 a reference to the object. We then assign to strb3 the value of strb2. This means that they both refer to the same object. They are still, however, independent variables themselves. Changing the value of strb2 will not change the value of strb3 - although while their values are still references to the same object, any changes made to the object through the sbrb2 variable will be visible through the strb3 variable. Here's a demonstration of that:
StringBuilder strb2 = new StringBuilder();
StringBuilder strb3 = strb2;
strb2.Append ("String");
strb2 = null;
Console.WriteLine (strb3);
 
 Output:
String
 
Here, we declare a variable strb2, create a new StringBuilder object, and assign to strb2 a reference to the object. We then assign to strb3 the value of strb2. We then call the Appendstrb2 variable. After this, we set the strb2null (a value which doesn't refer to any object). Finally, we print out the results of calling the ToString method on the StringBuilder object via the reference held in the strb3"String" is displayed, demonstrating that even though the value of strb2 has changed, the data within the object it used to refer to hasn't - and strb3 still refers to that object. method on this object via the reference held in the variable to variable.
Class types, interface types, delegate types and array types are all reference types. 

what is a value type?

While reference types have a layer of indirection between the variable and the real data, value types don't. Variables of a value type directly contain the data. Assignment of a value type involves the actual data being copied. Take a simple struct, for example:
public struct struct1{
public int i;
}
 
Wherever there is a variable of type struct1, the value of that variable contains all the data - in this case, the single integer value. An assignment copies the value, as demonstrated here:
struct1 one = new struct1();
one.i=10;
struct1 two = one;
struct1.i=11;
Console.WriteLine(two.i);
 
 Output:
10
 
Here, two.i has the value 10, because that's the value one.i has when the assignment two=one occurs - the values in two are independent of the values in one apart from when the assignment takes place.  
Simple types (such as float, int, char), enum types and struct types are all value types.
Note that many types (such as string) appear in some ways to be value types, but in fact are reference types. These are known as immutable types. This means that once an instance has been constructed, it can't be changed. This allows a reference type to act similarly to a value type in some ways - in particular, if you hold a reference to an immutable object, you can feel comfortable in returning it from a method or passing it to another method, safe in the knowledge that it won't be changed behind your back. This is why, for instance, the string.Replace doesn't change the string it is called on, but returns a new instance with the new string data in - if the original string were changed, any other variables holding a reference to the string would see the change, which is very rarely what is desired. 
Constrast this with a mutable (changeable) type such as ArrayList - if a method returns the ArrayList reference stored in an instance variable, the calling code could then add items to the list without the instance having any say about it, which is usually a problem. Having said that immutable reference types act like value types, they are not value types, and shouldn't be thought of as actually being value types.

No comments:

Post a Comment