Reference and Value Types | | One of the most common mistakes developers make when learning .NET is confusing Reference and Value Types with Passing values by Reference or Value.
Is this a big deal? YES! It's a very big deal.
So let's go through the basics first:
Values types break down like this...
(From MSDN)
Value types include:
All numeric data types
Boolean, Char, and Date
All structures, even if their members are reference types
Enumerations, since their underlying type is always Byte, Short, Integer, or Long
Reference types include:
String
All arrays, even if their elements are value types
Class types, such as Form
Delegates
Notice the part about the CLASS Types! Yes, every object you create is a Reference type. What does that mean? More than anything else, it means that if you pass it ByRef or ByVal, any changes you make to it are going to made to the object itself. Technically speaking that's an oversimplification, but for all intents and purposes, it's correct. (Passing a Reference type ByVal passes a copy of a pointer to the value).
This involves a good amount of overhead and can induce subtle (and not so subtle) bugs in your app. Forget the fact that you learned ByVal only passes a copy of the obect in CS 101. Forget that it worked in prior versions of VB and C++.
Now, if you pass a value type what actually happens? Everything in .NET is an object and derived from the Object base class. So what happens with any object is that you pass a reference to it either way. However, if you use a Value type, it acts like it's actually passing its own data.
So what happens if you have a Reference type composed exclusively of Value Types? It will behave just like a reference type (gasp) but it's members will behave like Value types. So if you copy or close an object, keep this in mind. Now, if you pass a Structure for instance, what happens? Even if it is completely composed of Reference types, it will behave as a Value type, because after all, that's what it is.
What happens if you try to Copy or Clone a Reference Type? That's a neat question. The short answer is that it will behave just like you'd expect a reference type to behave. This would really be limiting though if there was no way around it. After all, what if I want a copy of something that I want to manipulate but don't want to risk hurting the original object? Meet Deep and Shallow Clones. In this instance, you'll make a Shallow Clone which means that the cloned object is still pointing back to the original object. But, you can create new properties in a clone method thereby decoupling the cloned/copied object from its originator. (Deep vs. Shallow clones is the subject of another article, the intent of this article is just to raise some awareness).
In sum, Reference and Value types are much much different in .NET than anything prior to it. If you don't get under the hood and understand they way they work, you are going to have it bite you at some point....so I encourage you to read through the documentation and learn as much as you can about it. (If you are really ambitious, break out the disassembler and see what's really happening - I'll have an article on just how to do this shortly). |