Earlier in this chapter you saw how local scope keeps you from having a variable that is defined in one subroutine changed by being used in some other subroutine. This means that you can use local scope to hide data. That data privacy helps keep the data from being contaminated by other segments of the program.
However, hiding is not always a good thing (in courtship, for example). Even in programs, there are times when you want multiple procedures to have access to a single piece of data. In terms of this chapter's earlier example, you might want both btnCalc and btnExit to have access to MyVariable . You can make this happen by defining a data item so that it has module scope.
Module scope means that every procedure within that module has full access to the data item. For the moment, you can think of the program form as being the module that grants module scope. Look carefully at Listing 8.6. It presents all the code currently associated with the form named frmLocalScope .
Listing 8.6 All the Program Code for the Module frmLocalScope
Public Class frmLocalScope Inherits System.Windows.Forms.Form Dim MyVariable As Integer Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As _ System.EventArgs) Handles MyBase.Load End Sub Private Sub btnCalc_Click(ByVal sender As System.Object, ByVal e As _ System.EventArgs) Handles btnCalc.Click MyVariable = 20 End Sub Private Sub btnExit_Click(ByVal sender As System.Object, ByVal e As _ System.EventArgs) Handles btnExit.Click MyVariable = 20 Me.Dispose() End Sub End Class
Notice that the definition of MyVariable has been moved from the btnCalc object's Click() event to the third line from the top of the program in Listing 8.6. In Listing 8.2, the definition of MyVariable is within the btnCalc object's Click() event. Because the definition occurs within the btnCalc subroutine, it has local scope in Listing 8.2.
In Listing 8.6, notice the first line:
Public Class frmLocalScope
and the last line:
As you might guess, everything between these two lines defines the statement body for the class named frmLocalScope . With the exception of four lines in Listing 8.6, Visual Basic .NET automatically wrote the class definition for frmLocalScope . Collectively, you can call all the code in Listing 8.6 the frmLocalScope Class module; frmLocalScope is the module to which module scope applies.
The third line in Listing 8.6 is the definition of MyVariable . Note that the definition of MyVariable is outside any procedure but is contained within the frmLocalScope module. Because the class definition for frmLocalScope is the module for the program, MyVariable has module scope.
The code in Listing 8.6 compiles without error, even though you have accessed MyVariable in both the btnCalc and btnExit objects' Click() events. Your earlier attempts to use MyVariable in btnExit objects' Click() event drew error messages because MyVariable was out of scope.
In Listing 8.6, because the definition of MyVariable occurs outside any procedure, MyVariable has module scope. Because it has module scope, you can use the variable at any point in the module after it has been defined (that is, after the Dim statement in line 3). Therefore, the good news is that MyVariable is accessible everywhere in the frmLocalScope class definition. The bad news is also that MyVariable is accessible everywhere in the frmLocalScope class definition. Data items that have module scope cannot hide from anything within the module. By giving MyVariable module scope, you give up data privacy for MyVariable in the frmLocalScope class definition.
When should you sacrifice the benefits of data privacy and use module scope? Alas, I cannot fully answer that question now because there are additional details about Visual Basic .NET that you need to understand first. However, you will learn more about this in later chapters.
Dim , Private , and Module Scope
The placement of the definition of MyVariable in Listing 8.6 gives it module scope. As discussed in the preceding section, module scope means that everything within the module has access to MyVariable and can change the value of MyVariable if it wants to. MyVariable has module scope with respect to the frmLocalScope class definition. Stated another way, everything within the frmLocalScope class knows the lvalue of MyVariable .
What about access to MyVariable outside the frmLocalScope class definition? By default, the definition of MyVariable , as shown in this statement, is private to the frmLocalScope class:
Dim MyVariable As Integer
This means that if the program had multiple forms and modules, none of those other forms or modules would be able to access the variable named MyVariable .
The scope of MyVariable is confined to the frmLocalScope module, and it is a common convention in Visual Basic .NET to replace the module scope definition shown in Listing 8.6:
Dim MyVariable As Integer
with this definition:
Private MyVariable As Integer
Most Visual Basic .NET programmers prefer this notation because it reaffirms that the variable is private to this module and is not available for use in any other form or module in the program.