All variables that refer to objects are called object variables. (The other type of variables are value variables, which store base data types, such as characters, integers, strings, and dates.) In declaring object variables, we usually use the New keyword, which is the only way to create a new object. If you omit this keyword from a declaration, only a variable of the Customer type will be created, but no instance of the Customer class will be created in memory, and the variable won’t point to an actual object. The following statement declares a variable of the Customer type, but doesn’t create an object:
Dim Cust As Customer
Code language: PHP (php)
If you attempt to access a member of the Customer class through the Cust variable, the infamous NullReferenceException will be thrown. The description of this exception is Object reference not set to an instance of an object, which means that the Cust variable doesn’t point to an instance of the Customer class. Actually, the editor will catch this error and will underline the name of the variable. If you hover the mouse pointer over the name of the variable in question, the following explanation will appear on a ToolTip box: Variable Cust is used before it has been assigned a value. A Null Reference exception could result at runtime. Why bother declaring variables that don’t point to specific objects? The Cust variable can be set later in the code to reference an existing instance of the class:
Dim Cust As Customer
Dim Cust2 As New Customer
Cust = Cust2
Code language: PHP (php)
After the execution of the preceding statements, both variables point to the same object in memory, and you can set the properties of this object through either variable. You have two object variables, but only one object in memory because only one of them was declared with the New keyword. To set the Company property, you can use either one of the following statements, because they both point to the same object in memory:
Cust.CompanyName = "New Company Name"
Code language: JavaScript (javascript)
or
Cust2.CompanyName = "New Company Name"
Code language: JavaScript (javascript)
The Cust variable is similar to a shortcut. When you create a shortcut to a specific file on your desktop, you’re creating a reference to the original file. You do not create a new file or a copy of the original file. You can use the shortcut to access the original file, just as we can use the Cust variable to manipulate the properties of the Cust2 object in the preceding code sample.
It’s also common to declare object variables without the New keyword when we know we’re going to use them later in our code, as shown in the following loop:
Dim LI As ListViewItem
For row = 0 To 20
LI = New ListViewItem
LI.Text = "....."
' more statements to set up the LI variable
ListView1.Items.Add(LI)
Next
Code language: PHP (php)
The LI variable is declared once, and we initialize it many times in the following loop. The first statement in the loop creates a new ListViewItem object, and the last statement adds it to the ListView control. Another common scenario is to declare an object variable without initializing it at the form’s level and initialize it in a procedure, while using its value in other procedures.
When to Use the New Keyword
Many programmers are confused by the fact that most object variables must be declared with the New keyword, whereas some types don’t support the New keyword. If you want to create a new object in memory (which is an instance of a class), you must use the New keyword. When you declare a variable without the New keyword, you’re creating a reference to an object, but not a new object. Only shared classes must be declared without the New keyword. If in doubt, use the New keyword anyway, and the compiler will let you know immediately whether the class you’re instantiating has a constructor. If the New keyword is underlined in error, you know that you must delete the New keyword from the declaration.
Exploring Value Types
Okay, if the variables that represent objects are called object variables and the types they represent are called reference types, what other variables are there? They’re the regular variables that store the basic data types, and they’re called value variables because they store values. An integer, or a string, is not stored as an object for efficiency. An Integer variable contains an actual value, not a pointer to the value. Imagine if you had to instantiate the Integer class every time you needed to use an Integer value in your code. Not that it’s a bad idea, but it would scare away most VB developers. Value variables are so common in programming and they’re not implemented as classes for efficiency. Whereas objects require complicated structures in memory, the basic data types are stored in a few bytes and are manipulated much faster than objects. Consider the following statements:
Dim age1, age2 As Integer
age2 = 29
age1 = age2
age2 = 40
Code language: PHP (php)
When you assign a value variable to another, the actual value stored in the variable overwrites the current value of the other variable. The two variables have the same value after the statement that assigns the value of age2 to the variable age1, but they’re independent of one another. After the execution of the last statement, the values of age1 and age2 are different again. If they were object variables, they would point to the same object after the assignment operation, and you wouldn’t be able to set their values separately. You’d be setting the properties of the same object. Value types are converted to objects as soon as you treat them as objects. As soon as you enter a statement like the following, the intValue variable is converted to an object:
intValue.MinValue
Code language: CSS (css)
You’ll rarely use the methods of the base types, but you can turn value variables into object variables at any time. This process is known as boxing (the conversion of a value type to an object).
Exploring Reference Types
To better understand how reference types work, consider the following statements that append a new row with two subitems to a ListView control. (The control’s item is an object of the ListView Item type.):
ListView1.Items.Clear
Dim LI As New ListViewItem
LI.Text = "Item 1"
LI.SubItems.Add("Item 1 SubItem 1.a")
LI.SubItems.Add("Item 1 SubItem 1.b")
ListView1.Items.Add(LI)
Code language: PHP (php)
After the execution of the preceding statements, the ListView control contains a single row. This row is an object of the ListViewItem type and exists in memory on its own. Only after the execution of the last statement is the ListViewItem object referenced by the LI variable associated with the ListView1 control.
To change the text of the first item, or its appearance, you can manipulate the control’s Items collection directly, or change the LI variable’s properties. The following pairs of statements are equivalent:
ListView1.Items(0).Text = "Revised Item 1"
ListView1.Items(0).BackColor = Color.Cyan
Code language: JavaScript (javascript)
and
LI.Text = "Revised Item 1"
LI.BackColor = Color.Cyan
Code language: JavaScript (javascript)
There’s yet another method to access the ListView control’s items. Create an object variable that references a specific item and set the item’s properties through this variable:
Dim selItem As ListViewItem
selItem = ListView1.Items(0)
selItem.Text = "new caption"
selItem.BackColor = Color.Silver
Code language: PHP (php)
These statements are not new to you; you’ve seen these techniques in action in Chapter 9, ‘‘The TreeView and ListView Controls,” where you learned to program the ListView control. Now you can really understand how they work.
A final question for testing your OOP skills: What do you think will happen if you set the LI variable to nothing? Should the control’s row disappear? The answer is no. If you thought otherwise, take a moment now to think about why deleting a variable doesn’t remove the object from memory. The LI variable points to an object in memory; it’s not the object. The New keyword created a new ListViewItem object in memory and assigned its address to the variable LI. The statement that added the LI variable to the control’s Items collection associated the object in memory with the control. By setting the LI variable to nothing, we simply removed the pointer to the ListViewItem object in memory, not the object itself. To actually remove the control’s first item, you must call the Remove method of the LI variable:
LI.Remove
Code language: CSS (css)
This statement will remove the ListViewItem object from the control’s Items collection, but the actual object still lives in the memory. If you execute the following statement, the item will be added again to the control:
ListView1.Items.Add(LI)
Code language: CSS (css)
So to sum up, the ListViewItem object exists in memory and is referenced by the LI variable. The Remove method removes the item from the control; it doesn’t delete it from the memory. If you remove the item from the control and then set the LI variable to Nothing, the object will also be removed from memory.
By the way, the ListViewItem object won’t be deleted instantly. The CLR uses a special mechanism to remove objects from memory, the Garbage Collector (GC). The GC runs every so often and removes from memory all objects that are not referenced by any variable. These objects eventually will be removed from memory, but we can’t be sure when. (There’s no way to force the GC to run on demand.) The CLR will start the GC based on various criteria (the current CPU load, the amount of available memory, and so on). Because objects are removed automatically by the CLR, we say that the lifetime of an object is nondeterministic. However, you can rest assured that the object will eventually be removed from memory. After you set the LI variable to Nothing and remove the corresponding item from the ListView control, you’re left with a ListViewItem object in memory that’s not referenced by any other entity. This object will live a little longer in the memory, until the GC gets a chance to remove it and reclaim the resources allocated to the object. Here are the statements I’ve used for this experiment:
' Create a new ListViewItem object
Dim LI As New ListViewItem
LI.Text = "Item 1"
LI.SubItems.Add("Item 1 SubItem 1.a")
LI.SubItems.Add("Item 1 SubItem 1.b")
' add it to the ListView control
ListView1.Items.Add(LI)
MsgBox("Item added to the list." & vbCrLf & _
"Click OK to modify the appearance " & _
"of the top item through the LI variable.")
' Edit the object's properties
' The new settings will affect the appearance of the
' item on the control immediately
LI.Text = "ITEM 1"
LI.Font = New Font("Verdana", 10, FontStyle.Regular)
LI.BackColor = Color.Azure
MsgBox("Item's text and appearance modified." & _
vbCrLf & "Click OK to modify the " & _
"appearance of the top item through " & _
"the ListView1.Items collection.")
' Change the first item on the control directly
' Changes also affect the object in memory
ListView1.Items(0).BackColor = Color.LightCyan
LI.SubItems(2).Text = "Revised Subitem"
' Remove the top item from the control
MsgBox("Will remove the top item from the control.")
LI.Remove()
MsgBox("Will restore the deleted item")
' The item was removed from list, but not deleted
' We can add it to the control's Items collection
ListView1.Items.Add(LI)
MsgBox("Will remove object from memory")
' Remove it again from the control
LI.Remove()
' and set it to Nothing
LI = Nothing
' We can no longer access the LI object.
MsgBox("Can I access it again? " & vbCrLf & _
"NO, YOU'LL GET AN EXCEPTION WHEN THE " & _
"FOLLOWING STATEMENT IS EXECUTED!")
ListView1.Items.Add(LI)
Code language: PHP (php)