Qua is most likely correct; conveying what is happening is easiest with pictures, but with words it's not so bad either.
There are two types of variables in .NET: reference types and value types. Each behaves differently, and it is imperative that you understand how each is used.
Analogies work great too, so for the purposes of analogy suppose we have a warehouse full of boxes, and we want to be able to talk about a particular box.
Value Types
Value types are the easiest to explain, and work intuitively. All structures are value types, and almost all primitive types (Integer, Double, etc.) are value types. When you declare a value type like this:
Dim value as Integer = 10
...the compiler allocates memory for an Integer variable, stores the value in that memory, and the name
value points to the memory location. When you change the value, the value that is stored in the memory location is changed. When you assign one value type to another:
value2 = value
... the compiler
copies the value of the right-hand side into the left-hand side. Both variables represent unique locations in memory.
In our warehouse, it's easy to describe how value types work. When I ask for a new integer, I get a box. I can put whatever I want in that box, but I have to remove its old contents before putting it in another box. If I want box 2 to have what's in box 1, I have to find an item identical to what's in box 1 and place it in box 2. If I later come back and change what's in box 2, box 1 remains unchanged.
Reference Types
Reference types are types that might take up a lot of space; every class is a reference type and String is a reference type as well. When you declare and instantiate a new reference type:
Dim value As New SomeClass()
... the compiler allocates memory on the heap for a
SomeClass object, and stores the address of that memory in
value. When you assign a reference type to another:
value2 = value
... the compiler copies the
address of the right-hand side and stores it in the left-hand variable. Now, you have two variables that reference the same object in memory. If you change something via value2, value1 will reflect the change.
In our warehouse, reference-type variables are easy to explain. When I ask for a new reference-type box, someone creates the right box, places it on a shelf, then hands me a piece of paper that tells me where the box is. If I want to change the contents of the box, I find the box and change its contents.
The line of code
value2 = value in this case behaves differently; it's as if I found a new piece of paper and wrote the address on that one too. Now, it doesn't matter which piece of paper I use to find the box, there's only one box.
If I don't want this to happen, I have to explicitly tell my workers to find a new box, make sure its contents are identical to the old box, then give me the address of the new box. This is a tricky point for a lot of people.
Summary- Value types are primitive types and structures.
- Value types store a value.
- When you assign a value type to another, a copy of the first value is made and stored in the other value.
- Reference types are classes and strings.
- Reference types store the location of the object they reference.
- When you assign a reference type to another, only the address is copied.
- If you don't want to alter the first object, you have to manually make a copy of it and store it in the second object.
Strings are weird
Strings are reference types. Strings are also immutable. What this means is that if I declare a string, then assign that string to a second variable, then change the string via either variable, I still have two unique string objects:
Why? Strings are immutable; this means once a string is created in memory, you cannot alter it. When the string is changed, a new string is returned. So, when you assign two strings to each other, it behaves like a reference and you get two variables that point to the same string. BUT, if I change the value of one of the variables, it points to a new string; since the original variable still points to the old string, strings behave like value types.
The following application demonstrates some of the concepts:
Code:
Module Module1
Sub Main()
Console.WriteLine("Value types:")
Dim intValue As Integer = 10
Dim intValue2 As Integer = intValue
Console.WriteLine("Before change: {0} {1}", intValue, intValue2)
intValue2 = 15
Console.WriteLine("After change: {0} {1}", intValue, intValue2)
Console.WriteLine()
Console.WriteLine("Reference types:")
Dim clsReference As SomeClass = New SomeClass("one")
Dim clsReference2 As SomeClass = clsReference
Console.WriteLine("Same reference? {0}", Object.ReferenceEquals(clsReference, clsReference2))
Console.WriteLine("Before assignment: {0} {1}", clsReference.value, clsReference2.value)
clsReference2.value = "two"
Console.WriteLine("After assignment: {0} {1}", clsReference.value, clsReference2.value)
Console.WriteLine("Copying...")
clsReference2 = New SomeClass(clsReference.value)
Console.WriteLine("Same reference? {0}", Object.ReferenceEquals(clsReference, clsReference2))
Console.WriteLine("Before assignment: {0} {1}", clsReference.value, clsReference2.value)
clsReference2.value = "three"
Console.WriteLine("After assignment: {0} {1}", clsReference.value, clsReference2.value)
Console.WriteLine()
Console.WriteLine("Strings:")
Dim value As String = "one"
Dim value2 As String = value
Console.WriteLine("Same reference? {0}", Object.ReferenceEquals(value, value2))
Console.WriteLine("Before assignment: {0} {1}", value, value2)
value2 = "two"
Console.WriteLine("After assignment: {0} {1}", value, value2)
End Sub
End Module
Public Class SomeClass
Public value As String
Public Sub New(ByVal value As String)
Me.value = value
End Sub
End Class