Reference types store an address of their data, aka “pointer” on the portion of the memory called the “stack”. The actual data to which the pointer refers to is stored in an area of memory called the “heap”. Because reference types directly store the address “pointer” to the data rather than the data itself, assigning one reference variable to another doesn’t copy the data over. Instead, it merely creates a second copy of the “pointer”, which also refers to the same memory on the heap as the original. Whenever you assign or make changes to either reference variable, having been referenced to each other, you will in fact be making changes to the same actual data both references are pointing to.
1: struct Numbers{
2: public int val;
3: public Numbers( int _val){
4: val = _val; 5: }6: public override ToString(){
7: return val.ToString();
8: } 9: } 10: 11: //Now create an instance of the Numbers structure in your Main method
12: //and assign that instance to a second instance then modify both.
13: Numbers n1 = new Numbers(0);
14: Numbers n2 = n1; 15: n1.val += 1; 16: n2.val += 2;17: Console.WriteLine("n1 = {0}, n2 = {1}", n1, n2);
The above Numbers struct is a value type and it’s data will be stored on the memory stack, any new instances created will create a new block on the memory stack. When the above code is run it would display “n1 = 1, n2 = 2” because of the assigning of each value type results in two distinct values.
If you changed the Numbers type declaration from a struct to a class the same application would display ”n1 = 3, n2 = 3”. Changing Numbers from a struct to a class causes it to be a reference type rather than a value type. Now both variables point to the same data on the heap, so updating the variables n1 and n2 both update the reference they both point to.
The .Net Framework has some 2,500 built in in reference types and anything not derived from System.ValueType is a reference type.
Common reference types:
| Type | Used for |
| System.Object | Most general type in the .NET Framework. Any type can be converted to System.Object. |
| System.String | Text data. |
| System.Text.StringBuilder | Dynamic text data. |
| System.Array | Arrays of data, this is the base class for all arrays. |
| System.IO.Stream | Buffer for file, device and network I/O. This is an abstract base class. |
| System.Exception | Handling system and application defined exceptions, task specific exceptions derive from this type. |
A few words on References, Memory and Garbage Collection
Browsing around the net you will find a lot written about value types and reference types and where each is stored in memory. I personally found quite a few which say the statement "value types go on the stack, reference types go on the heap” is simply untrue. I am not going to spend a bunch of time discussing whether or not this is true. Mainly because it is and it is not true. It all depends on how you implement the variables and the level of abstraction in your discussion. This discussion is not within the scope of passing this certification. Your knowledge of memory and how it works with value and reference types in the .NET Framework at its most basic way will shape your understanding. I recommend you read all you can on the subject, more knowledge will make you a better programmer. Here is a good article on the subject, there are many more.
Garbage collection in the Microsoft .NET common language runtime (CLR) environment relieves the developer a great deal from tracking memory usage and knowing when to free memory. As a good programmer you still will want to understand how it works. Garbage collection is what manages the heap and only occurs when needed or triggered by a call to GC.Collect. While developing in the C# language you should never make a call for garbage collection. The .NET Framework has been optimized to handle garbage collection automatically for applications where most instances are short lived, except those that are allocated at the beginning of the application and making a call will disrupt the balance it has set for for garbage collection and possibly impact application performance. Understanding the nuances of programming with .NET and its statements such as the “using” statement and how it works with objects which implement System.IDisposable interface during garbage collection, are beyond the scope of this study. Although, knowledge of the“using” statement and it’s advantages in an implementation are part of being a good programmer. Once again, knowledge is power. Here is a good article on garbage collection.
