有多个同名变量时解析引用

更新:2007 年 11 月

当编译器尝试将名称引用与名称声明进行匹配时,它使用“最小范围”查找匹配的声明。这意味着它以进行引用的代码开始,并向外扩展到连续的包含元素级别。

如果要重写此搜索过程以指定一个在更大范围内声明的名称,必须用更大范围的包含元素“限定”名称。在某些情况下,可能还必须限定包含元素。有关名称限定的更多信息,请参见如何:限定已声明的元素名

如果应用程序需访问多个同名的编程元素,可能还必须限定名称引用。有关示例,请参见本帮助页中的“具有相同名称的类”和如何:区分两个名称相同的元素

最小范围

下面的示例显示了对两个同名变量的引用。

' 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

上面的示例在 container 模块中以不同的范围级别声明了两个变量,其名称都是 totalCount。当过程 showCount 在没有限定的情况下显示 totalCount 时,Visual Basic 编译器用最小范围(即 showCount 内的局部声明)来解析对声明的引用。当该过程用包含模块 container 来限定 totalCount 时,编译器用更大范围来解析对声明的引用。

其他包含元素的成员

在使用另一个类或结构的非共享成员时,必须首先使用指向该类或结构的实例的变量或表达式来限定成员名称。在下面的示例中,demoClass 是一个名为 class1 的类的实例。

Dim demoClass As class1 = New class1()
demoClass.someSub[(argumentlist)]

不能使用类名本身来限定不是 Shared (Visual Basic) 的成员。必须首先在对象变量(在此例中为 demoClass)中创建一个实例,然后通过变量名引用该实例。

如果类或结构具有 Shared 成员,可以用类或结构名称或用指向实例的变量或表达式来限定该成员。

模块没有任何单独的实例,在默认情况下,它的所有成员都为 Shared。因此,可以用模块名称来限定模块成员。

限定引用示例

下面的示例显示了对模块成员过程的限定引用。

' 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

上面的示例在一个项目的不同模块中声明了两个 Sub 过程,其名称都是 perform。每个过程在各自的模块内不用被限定即可指定,但如果从其他任何位置引用则必须被限定。由于 module3 中的最终引用不限定 perform,因此编译器无法解析该引用。

项目引用

若要使用在另一个项目中定义的 Public (Visual Basic) 元素,必须首先设置对该项目的程序集或类型库的“引用”。若要设置引用,请在“项目”菜单上单击“添加引用”,或使用 /reference (Visual Basic) 命令行编译器选项。

例如,可以使用 .NET Framework 的 XML 对象模型。如果设置对 System.Xml 命名空间的引用,可以声明和使用它的任何类,例如 XmlDocument。下面的示例使用 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

导入包含元素

可以使用 Imports 语句(.NET 命名空间和类型) 导入包含要使用的模块或类的命名空间。这样就可以引用在导入的命名空间中定义的元素,而不必完全限定它们的名称。下面的示例重写上面的示例,以导入 System.Xml 命名空间。

' 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

此外,Imports 语句还可以为每个导入的命名空间定义“导入别名”。这样可使源代码更简短且更易读。下面的示例重写上面的示例,以将 xD 用作 System.Xml 命名空间的别名。

' 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

Imports 语句并不能使其他项目中的元素可供您的应用程序使用。即,它不能取代设置引用。导入命名空间只是使得不再需要限定在该命名空间中定义的名称。

也可以使用 Imports 语句导入模块、类、结构和枚举。然后不必限定即可使用这些导入元素的成员。但是,必须始终使用计算为类或结构的实例的变量或表达式来限定类和结构的非共享成员。

具有相同名称的类

在创建对象的新实例时,可能必须用它所属的命名空间或类型库来限定该类。例如,System.Windows.FormsSystem.Web.UI.WebControls 命名空间都包含 Label 类(System.Windows.Forms.LabelSystem.Web.UI.WebControls.Label)。如果应用程序同时使用这两个类,或者如果定义了自己的 Label 类,则必须区分不同的 Label 对象。在变量声明中包括命名空间或导入别名。下面的示例使用了导入别名。

' 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()

命名指南

如果定义了两个或更多个具有相同名称的编程元素,则编译器试图解析对该名称的引用时会导致“名称多义性”。如果范围内有多个定义或者没有定义,则引用是不可解析的。有关示例,请参见本帮助页上的“限定引用示例”。

为所有元素提供唯一的名称可以避免名称多义性。然后就可以对任何元素进行引用,而不必用命名空间、模块或类来限定其名称。这样还可以减少意外引用错误元素的可能性。

请参见

任务

如何:修改项目属性和配置设置

如何:限定已声明的元素名

如何:区分两个名称相同的元素

概念

变量 (Visual Basic)

参考

Imports 语句(.NET 命名空间和类型)

New (Visual Basic)

Public (Visual Basic)

其他资源

对已声明元素的引用