Resolving a Reference When Multiple Variables Have the Same Name
When the compiler attempts to match a name reference to a name declaration, it looks for the matching declaration with the narrowest scope. This means it starts with the code making the reference and works outward through successive levels of containing elements.
If you want to override this search process and specify a name declared in a broader scope, you must qualify the name with the containing element of the broader scope. In some cases, you might also have to qualify the containing element. For more information about name qualification, see How to: Qualify a Declared Element Name.
You might also have to qualify a name reference if your application has access to more than one programming element that has the same name. For examples, see "Classes with the Same Name" on this Help page and How to: Distinguish Between Two Elements with the Same Name.
The following example shows references to two variables with the same name.
' Assume these two modules are both in the same assembly. Module container Public totalCount As Integer = 1 Public Sub showCount() Dim totalCount As Integer = 6000 ' The following statement displays the local totalCount (6000). MsgBox("Unqualified totalCount is " & CStr(totalCount)) ' The following statement displays the module's totalCount (1). MsgBox("container.totalCount is " & CStr(container.totalCount)) End Sub End Module Module callingModule Public Sub displayCount() container.showCount() ' The following statement displays the containing module's totalCount (1). MsgBox("container.totalCount is " & CStr(container.totalCount)) End Sub End Module
The previous example declares two variables, each named totalCount, at different levels of scope in module container. When the procedure showCount displays totalCount without qualification, the Visual Basic compiler resolves the reference to the declaration with the narrowest scope, namely the local declaration inside showCount. When it qualifies totalCount with the containing module container, the compiler resolves the reference to the declaration with the broader scope.
Members of Other Containing Elements
When you use a nonshared member of another class or structure, you must first qualify the member name with a variable or expression that points to an instance of the class or structure. In the following example, demoClass is an instance of a class named class1.
Dim demoClass As class1 = New class1() demoClass.someSub[(argumentlist)]
You cannot use the class name itself to qualify a member that is not Shared (Visual Basic). You must first create an instance in an object variable (in this case demoClass) and then reference it by the variable name.
If a class or structure has a Shared member, you can qualify that member either with the class or structure name or with a variable or expression that points to an instance.
A module does not have any separate instances, and all its members are Shared by default. Therefore, you qualify a module member with the module name.
Qualified Reference Example
The following example shows qualified references to module member procedures.
' Assume these three modules are all in the same assembly. Module module1 Public Sub perform() MsgBox("module1.perform() now returning") End Sub End Module Module module2 Public Sub perform() MsgBox("module2.perform() now returning") End Sub Public Sub doSomething() ' The following statement calls perform in module2, the active module. perform() ' The following statement calls perform in module1. module1.perform() End Sub End Module Module module3 Public Sub callPerform() ' The following statement calls perform in module1. module1.perform() ' The following statement makes an unresolvable name reference ' and therefore generates a COMPILER ERROR. perform() ' INVALID statement End Sub End Module
The previous example declares two Sub procedures, both named perform, in different modules in a project. Each one can be specified without qualification within its own module but must be qualified if referenced from anywhere else. Because the final reference in module3 does not qualify perform, the compiler cannot resolve that reference.
References to Projects
To use Public (Visual Basic) elements defined in another project, you must first set a reference to that project's assembly or type library. To set a reference, click Add Reference on the Project menu, or use the /reference (Visual Basic) command-line compiler option.
For example, you can use the XML object model of the .NET Framework. If you set a reference to the System.Xml namespace, you can declare and use any of its classes, such as XmlDocument. The following example uses XmlDocument.
' Assume this project has a reference to System.Xml ' The following statement creates xDoc as an XML document object. Dim xDoc As System.Xml.XmlDocument
Importing Containing Elements
You can use the Imports Statement (.NET Namespace and Type) to import the namespaces that contain the modules or classes that you want to use. This enables you to refer to the elements defined in an imported namespace without fully qualifying their names. The following example rewrites the previous example to import the System.Xml namespace.
' Assume this project has a reference to System.Xml ' The following statement must precede all your declarations. Imports System.Xml ' The following statement creates xDoc as an XML document object. Dim xDoc As XmlDocument
In addition, the Imports statement can define an import alias for each imported namespace. This can make the source code shorter and easier to read. The following example rewrites the previous example to use xD as an alias for the System.Xml namespace.
' Assume this project has a reference to System.Xml ' The following statement must precede all your declarations. Imports xD = System.Xml ' The following statement creates xDoc as an XML document object. Dim xDoc As xD.XmlDocument
The Imports statement does not make elements from other projects available to your application. That is, it does not take the place of setting a reference. Importing a namespace just removes the requirement to qualify the names defined in that namespace.
You can also use the Imports statement to import modules, classes, structures, and enumerations. You can then use the members of such imported elements without qualification. However, you must always qualify nonshared members of classes and structures with a variable or expression that evaluates to an instance of the class or structure.
Classes with the Same Name
When you create a new instance of an object, you might have to qualify the class with the namespace or type library to which it belongs. For example, the System.Windows.Forms and System.Web.UI.WebControls namespaces both contain a Label class (System.Windows.Forms.Label and System.Web.UI.WebControls.Label). If your application uses both, or if it defines its own Label class, you must distinguish the different Label objects. Include the namespace or import alias in the variable declaration. The following example uses the import alias.
' The following statement must precede all your declarations. Imports win = System.Windows.Forms, web = System.Web.UI.WebControls ' The following statement references the Windows.Forms.Label class. Dim winLabel As New win.Label()
When you define two or more programming elements that have the same name, a name ambiguity can result when the compiler attempts to resolve a reference to that name. If more than one definition is in scope, or if no definition is in scope, the reference is irresolvable. For an example, see "Qualified Reference Example" on this Help page.
You can avoid name ambiguity by giving all your elements unique names. Then you can make reference to any element without having to qualify its name with a namespace, module, or class. You also reduce the chances of accidentally referring to the wrong element.