类型提升 (Visual Basic)

在模块中声明编程元素时,Visual Basic 会将其范围提升到包含该模块的命名空间。 这称为“类型提升”。

下面的示例演示某个模块和该模块的两个成员的主干定义。

Namespace projNamespace
    Module projModule
        Public Enum basicEnum As Integer
            one = 1
            two = 2
        End Enum 
        Public Class innerClass
            Shared Sub numberSub(ByVal firstArg As Integer)
            End Sub 
        End Class 
    End Module 
End Namespace

在 projModule 中的模块级别上声明的编程元素将被提升到 projNamespace。 在前面的示例中,提升了 basicEnum 和 innerClass,但是没有提升 numberSub,因为它不是在模块级别上声明的。

类型提升的结果

类型提升的结果是一个限定字符串不需要包括模块名称。 下面的示例对前面示例中的过程发出两个调用。

Sub usePromotion()
    projNamespace.projModule.innerClass.numberSub(projNamespace.projModule.basicEnum.one)
    projNamespace.innerClass.numberSub(projNamespace.basicEnum.two)
End Sub

在前面的示例中,第一个调用使用完全限定字符串。 但由于进行了类型提升,因此这不是必需的。 第二个调用也访问模块的成员,但在限定字符串中不包括 projModule。

类型提升的失效

如果命名空间中的成员与某个模块成员同名,则对该模块成员的类型提升将会失效。 下面的示例演示同一命名空间中枚举和模块的主干定义。

Namespace thisNamespace
    Public Enum abc
        first = 1
        second
    End Enum 
    Module thisModule
        Public Class abc
            Public Sub abcSub()
            End Sub 
        End Class 
        Public Class xyz
            Public Sub xyzSub()
            End Sub 
        End Class 
    End Module 
End Namespace

在前面的示例中,Visual Basic 无法将类 abc 提升到 thisNameSpace,因为在命名空间级已存在同名的枚举。 若要访问 abcSub,必须使用完全限定字符串 thisNamespace.thisModule.abc.abcSub。 但是,仍会提升 xyz 类,您可以使用较短的限定字符串 thisNamespace.xyz.xyzSub 来访问 xyzSub。

分部类型提升的失效

如果模块内的类或结构使用 分部 (Visual Basic) 关键字,则对该类或结构的类型提升会自动失效,无论命名空间是否具有同名的成员。 模块中的其他元素仍然符合类型提升的条件。

**结果。**分部定义的类型提升失效可能导致意外的结果,甚至导致编译器错误。 下面的示例演示类的主干分部定义,其中一个定义位于模块内。

Namespace sampleNamespace
    Partial Public Class sampleClass
        Public Sub sub1()
        End Sub 
    End Class 
    Module sampleModule
        Partial Public Class sampleClass
            Public Sub sub2()
            End Sub 
        End Class 
    End Module 
End Namespace

在前面的示例中,开发人员可能期望编译器合并 sampleClass 的两个分部定义。 但是,编译器不考虑 sampleModule 内分部定义的提升。 因此,它尝试编译两个名称均为 sampleClass 但具有不同限定路径的不同类。

只有在两个分部定义的完全限定路径相同时,编译器才会对这两个分部定义进行合并。

建议

下面的建议提供了良好的编程做法。

  • **唯一名称。**当您可以完全控制编程元素的命名时,在所有位置使用唯一名称始终是一个好办法。 相同的名称需要额外的限定,并可能使代码难以阅读, 还可能导致难以发现的错误和意外的结果。

  • **完全限定。**当您在同一命名空间中使用模块和其他元素时,最安全的方法是对所有编程元素始终使用完全限定。 如果某个模块成员的类型提升失效,而您没有完全限定该成员,则无意中可能会访问另一个编程元素。

请参见

任务

如何:控制变量的范围 (Visual Basic)

参考

Module 语句

Namespace 语句

分部 (Visual Basic)

概念

Visual Basic 中的范围

对已声明元素的引用 (Visual Basic)