Literals are nice, and constants and enumerations are nicer, but none of them can be altered once your program starts. This tends to make your application rigid and inflexible. If all of your customers are named "Fred," and they only place orders for $342.34, it probably won't be much of a limitation. But most users want more variety in their software. Variables are named containers for data, just like constants, but their contents can be modified throughout the run of an application. Also, they can contain both value types and reference types. Here's the basic syntax for defining a new variable.
Dim customerName As String
The Dim keywordoriginally from the word "dimension"defines a new variable; in this case, a variable named customerName with a data type of String. This named container is ready to hold any String value; assign to it string literals, other string variables, or the return value from functions that generate strings. Because it is a reference type, it can also be set to Nothing, a special Visual Basic value and keyword that means "this reference type has not yet been instantiated."
customerName = Nothing ' Nothing customerName = "Fred" ' Literal customerName = GetCustomerName(customerID) ' Function result
All variables contain their default value until set to something else. For reference types, the default is Nothing; for numeric values, the default is zero. Booleans default to False. You can include an initial assignment as part of the Dim statement to override the default assignment.
Dim countdownSeconds As Short = 60 Dim processingDate As Date = Today Dim customerName As String = GetCustomerName(customerID)
The last line in that code block shows a reference typeStringbeing assigned the String result of a function. You can also assign a brand-new instance of a reference instance to a reference type variable. And it's new. That is, it uses the special New keyword, which says, "I'm creating a new instance of the specific data type." There are a few different variations, but they all produce the same results.
' ----- One-line variation. Dim someString As New String ' ----- Another one-line variation. Dim someString As String = New String ' ----- Two-line variation. Dim someString As String someString = New String
Remember that reference types are buckets that contain directions for locating the actual data. When a reference data first springs into existence, it contains Nothing. That is, the bucket contains no instructions at all because there is no related data stored anywhere. When you assign a new instance to a reference type variable, that instance gets stored somewhere in memory, and instructions for locating that data are dumped into the bucket. In the previous code block, each use of the New keyword creates a new data instance somewhere in memory. This data's location is then assigned to the someString reference type variable.
Many classes include constructors, initialization routines that set up the initial values of the instance. You can call a constructor as part of the New clause. The String data type includes a constructor that lets you build an initial string. One of these special constructors lets you create a new string containing multiple copies of a specific character. The following statement assigns a string of 25 asterisks to the lotsOfStars variable.
Dim lotsOfStars As New String("*"c, 25)
Constructors are discussed in detail in Chapter 8, "Classes and Inheritance."
Dim statements can appear anywhere in a procedure, but by tradition they always appear right at the start of a procedure, before any other logic statements.
Sub MyProcedure() Dim myVariable As Integer ' ----- Additional code goes here... End Sub
As with constants, variables can be defined either within a procedure, or outside of a procedure but within a type. (Variables and constants declared outside of procedures are known as fields. Variables and constants declared inside of a procedure are known as local variables and local constants, respectively.) The Dim keyword is always used with in-procedure variable declarations. At the type level, the Dim keyword is replaced by one of the following access modifiers.
A single class or type may contain both fields and local variables and constants.
Class MyClass ' ----- Here's a field. Private InternalUseOnly As Boolean Sub MyProcedure() ' ----- Here's a local variable. Dim myVariable As Integer End Sub End Class
There are other syntax variations to the Dim statement, some of which I will discuss later in this chapter and in other chapters.
Scope and Lifetime
When you define a variable within a procedure, it has procedure-level scope. This means that you can use the variable anywhere within that procedure. Your procedure will likely have "block statements," those statements, such as For...Next and If...Then, that require more than one line of source code to complete. If you add a Dim statement between the starting and ending lines of one of these statements, that declared variable will have only block-level scope. It will be available only within that block of the procedure.
For counter = 1 To 10 Dim processResult As Integer ' ----- More code here. Next counter MsgBox(processResult) ' This line will fail
This code declares processResult within the For...Next block. So it's only available for use inside of that block; any attempted use outside of processResult outside of the For block generates an immediate error.
The lifetime of a procedure-level variable begins when the code first enters that procedure, and ends when the code exits the procedure. This is true for both procedure-level and block-level variables. This means that if you assign a block-level variable some value before exiting the block, it will still have that value if you reenter that block during the same procedure call.
For fields (class-level variables), the scope depends on the access level used when declaring the variable. The lifetime of a field begins when the class instance is created in code, and ends when the instance is destroyed or goes completely out of use.