类型提升 (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。 在前面的示例中,basicEnuminnerClass 被提升,但 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 仍会提升,你可以使用较短的限定字符串 xyzSub 来访问 thisNamespace.xyz.xyzSub

不完整类型的类型提升失败

如果模块中的类或结构使用 Partial 关键字,则无论命名空间是否具有同名的成员,该类或结构都会自动失败类型提升。 模块中的其他元素仍有资格进行类型升级。

后果。 部分定义的类型升级失败可能会导致意外结果甚至编译器错误。 下面的示例演示类的框架部分定义,其中一个在模块中。

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 ,但具有不同的限定路径。

仅当完全限定的路径相同时,编译器才会合并部分定义。

建议

以下建议表示良好的编程实践。

  • 唯一名称。 当你完全控制编程元素的命名时,最好在任何地方使用唯一的名称。 相同的名称需要额外的限定,并且会使代码难以阅读。 它们还可能导致细微的错误和意外结果。

  • 完全限定。 使用同一命名空间中的模块和其他元素时,最安全的方法是始终对所有编程元素使用完全限定。 如果对某个模块成员进行类型提升失败并且未完全限定该成员,可能会无意中访问不同的编程元素。

另请参阅