Working with Block-Level Scope
Scope relates to opportunity for use. When a name is in scope, you can use it; when a name is not in scope, you cannot use it.
There are several layers of scope in Visual Basic .NET. From the broadest to narrowest scope, there is namespace, type (applies equally to class, module, and structure), procedure, and block scope. Things declared in a broader scope are accessible to narrower, subordinate scopes directly. For example, a private class field is accessible to a procedure in the same class and will not cause a name conflict with a field with the same name in another class.
Additionally, narrower-scoped names are accessible to other areas of code using the member-of operator (.). For example, the ToString method is defined as a public method of Object. Because ToString is public, it is accessible outside the Object class, but you have to precede the call to ToString with a class reference and the member-of operator, class .ToString().
Variables declared in a procedure or block have procedure-level or block-level scope, respectively. A block in a procedure is narrower than the containing procedure, so procedure variables are accessible in a block, but block variables are not accessible in the containing procedure. As mentioned in Chapter 2, block scope is new in Visual Basic .NET.
Block-scoped variables are those variables introduced for the first time in a For Next, For Each, While End While, or If Then construct. Any variables introduced with a Dim statement in a block construct are accessible only in that block when Option Explicit is On. Consider the following code fragment, using an arbitrary block to demonstrate block scope behavior:
If (True) Then Dim I As Integer I = 10 End If I = 5
If Option Explicit is On, you will get a "name is not declared" error reported by the compiler at the last line, assuming that I is not defined in the containing procedure. If Option Explicit is Off, the compiler will report a "block-level variable hides variable in enclosing block error" because the implicit I in the statement I = 5 hides the explicit I in the If Then block. Further, when Option Explicit is Off, if I were first used in the block, then I would be accessible outside the block.
Consider another example:
Option Explicit Off If (True) Then I = 10 End If Debug.WriteLine(I)
This code writes 10 to the Output window.
If you want a variable to be accessible in an outer scope, move the declaration of the variable to the outer scope, as in this final example:
Option Explicit On Dim I As Integer If(True) Then I = 10 End If Debug.WriteLine(I)
The variable I is defined outside the block and consequently is accessible in both the scope where it is defined and the narrower scope of the If Then block.
A second detail to watch out for is that block variables have to be initialized between trips in and out of block scope to prevent unexpected results. When working with block scope, establish a consistent set of rules to prevent problems related to block scope. The following rules, if applied consistently, should preclude any problems: