Although it is not used all that often in Visual Basic .NET programs, an even more restrictive scope level than local scope is available within a subroutine or function. Block scope applies to all data items that are defined with a statement block. (Although we haven't covered the keywords fully, this is the proper time and place to discuss block scope.) The statements that can be used in conjunction with block scope are If-Then-Else , For- Next , and Do-Loop .
An example will help you understand how block scope works. To begin, remove the present code from the btnCalc object's Click() event and then add to it the code presented in Listing 8.5.
Listing 8.5 An Example of Block Scope
Dim i As Integer ' Local scope If i = 0 Then Dim j As Integer ' Start of block scope for j j = 10 ' Block scope for j End If ' End of block scope for j Debug.WriteLine(j)
Now if you try to compile the program, you get the following error message:
Name 'j' is not declared.
The line that causes the error message is the Debug.WriteLine(j) statement. This happens because you have defined the variable name j within the If-Then statement block. The statement block extends from the opening If statement to the closing End If statement. Any code between these keyword statements is considered part of the If statement block. The variable j , therefore, is in scope only from its Dim statement to the End If statement. Because Debug.WriteLine(j) attempts to use j outside its statement block, Visual Basic .NET issues an error message.
The Same Variable Name at Different Scope Levels
If you changed the references to j in Listing 8.5 to i , would you get a duplicate variable error message? The code fragment that changes the reference follows :
Dim i As Integer ' Local scope If i = 0 Then Dim i As Integer ' Start of block scope for i i = 10 ' Block scope for i End If ' End of block scope for i Debug.WriteLine(i)
In this case, you get an error message that states Variable 'i' hides a variable in an enclosing block . This happens because i is used in the If statement and, therefore, becomes part of the If statement block. Now you should move the definition of i outside the Click() event, toward the top of the program, after this statement:
Inherits System.Windows.Forms.Form Dim i as integer
When you compile the program now, does Visual Basic .NET issue the same error message?
The answer is no: If you move the definition of i outside the button's Click() event, you do not get a duplicate variable error message. The reason is because the second definition for variable i occurs at a different scope level. The first i is at the module scope level, and the second definition of i is at the block scope level. Variables defined at different scope levels can have the same name.
Another interesting issue to determine is which i is used in this statement from the preceding code block:
i = 10 ' Block scope for i
As the comment suggests, the assignment applies to the i defined at the block level. As a general rule, if two variables with the same name are both in scope, the most-recently defined variable is the variable that is being accessed. Note that the first i defined in the code fragment has a different scope level, called module scope, so it is in scope from its definition to the end of the module. (Module scope is explained in the next section. For the moment, just recognize that module scope is different from local scope.) This also means that its scope wraps around the scope for the variable i that is defined within the If statement block. However, the i that is defined within the If statement block takes precedence in the If statement block because it is the variable that was defined last.
Now determine which variable i is used in this statement:
It must be the i with module scope because the i with block scope no longer exists. It died when you left the If statement block.
As you can see, block scope is limited to whatever keyword pairs ( If-End If , For “Next , and so on) form the statement block. Any data item that is defined within a statement block has its scope limited to that statement block. This is similar to local scope in that local scope extends from the Dim within the subroutine or function to its End Sub or End Function statement.
Block scope extends from its Dim to the end of the statement block. However, because statement blocks usually appear within a procedure block, block scope is usually more restrictive.
Variables that employ block scope are a bit unusual. I could present a rather contrived example, but it's not really necessary to do so. You should remember that block scope exists because there may come a time when it proves useful to you.