Variables can exist in several places and in broader or narrower scopes. Sometimes this causes problems because it may be unclear to the compiler what the code means. For example, when a variable is defined at the procedure level and a variable with the same name exists in a block within the procedure, the variable in the block hides the variable with the same name in the outer scope. In Visual Basic .NET, this is referred to as shadowing. That is, the narrow scope variable shadows the outer scope variable.
At the block level, the compiler will report an error: "Block-level variable hides a variable in an enclosing block." An example of causation follows :
Sub Main() Dim V As Object If True Then Dim V As Object V = Nothing End If End Sub
V in the inner block hides the variable outside of the If...Then block. To resolve this problem, simply rename or remove the block-level variable. However, if the problem exists at the module, class, or structure level, you can use a variety of techniques to clarify your intent.
Suppose Module1 declares a module-level Integer I, and suppose Sub Main declares a local variable I. Within Main all references to I will shadow the variable in the outer, module scope. This scenario is demonstrated by the next code fragment:
Module Module1 Dim I As Integer Sub Main() Dim I As Integer I = 10 Debug.WriteLine(Module1.I) End Sub End Module
All references to I in Main refer to the I defined in Main. What if you wanted to modify the outer scope's I variable? In the case of a module, you would simply prefix the reference to I with the module name. Based on this fragment, if we wanted to refer to I in the outer scope, Module1.I would clearly indicate our intent to the compiler.
If the containing entity were a class, we would use the Me (reference to self) object, as in Me.I. The reason we can use the module name is that modules are for all intents and purposes classes with all shared members . The reason we cannot reliably use the class name and have to use Me is that classes are instantiated many times, and each object will have a different name.
Visual Basic .NET also introduces the Shadows keyword. Shadows is used when a subclass reintroduces a name in a superclass, hiding the name in the superclass and that is what you want to happen. I will defer the discussion of Shadows until Chapter 7, "Creating Classes," because it will be beneficial if inheritance and overloading methods are covered before we continue talking about the Shadows qualifier.