VB.NET是一款运行机制和Java类似的编程语言。其具有面向对象特性,能够支持代码托管,而且界面简单,结构稳定,为开发人员带来了极大的好处。在这里我们会通过对VB.NET类型提升的一些相关问题的解疑,来对这门语言进行深入的研究。
在模块中声明编程元素时,VB.NET会将其范围提升到包含该模块的命名空间。这称为VB.NET类型提升。
下面的示例演示某个模块和该模块的两个成员的主干定义。
- Namespace projNamespace
- Module projModule
- Public Enum basicEnum As Integer
- one = 1
- two = 2
- End Enum
- Public Class innerClass
- Public Sub numberSub(ByVal firstArg As Integer)
- End Sub
- End Class
- End Module
- End Namespace
在 projModule 中的模块级别上声明的编程元素将被提升到 projNamespace。在前面的示例中,提升了 basicEnum 和 innerClass,但是没有提升 numberSub,因为它不是在模块级别上声明的。
VB.NET类型提升的结果
类型提升的结果是一个限定字符串不需要包括模块名称。下面的示例对前面示例中的过程发出两个调用。
- Sub usePromotion()
- projNamespace.projModule.innerClass.numberSub
(projNamespace.projModule.basicEnum.one)- projNamespace.innerClass.numberSub(projNamespace.basicEnum.two)
- End Sub
在前面的示例中,***个调用使用完全限定字符串。但由于进行了类型提升,因此这不是必需的。第二个调用也访问模块的成员,但在限定字符串中不包括 projModule。
VB.NET类型提升的失效
如果命名空间中的成员与某个模块成员同名,则对该模块成员的类型提升将会失效。下面的示例演示同一命名空间中枚举和模块的主干定义。
- 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。
分部VB.NET类型提升的失效
如果模块内的类或结构使用分部 (Visual Basic) 关键字,则对该类或结构的类型提升会自动失效,无论命名空间是否具有同名的成员。模块中的其他元素仍然符合类型提升的条件。
结果。 分部定义的类型提升失效可能导致意外的结果,甚至导致编译器错误。下面的示例演示类的主干分部定义,其中一个定义位于模块内。
- Namespace sampleNamespace
- Public Partial Class sampleClass
- Public Sub sub1()
- End Sub
- End Class
- Module sampleModule
- Public Partial Class sampleClass
- Public Sub sub2()
- End Sub
- End Class
- End Module
- End Namespace
在前面的示例中,开发人员可能期望编译器合并 sampleClass 的两个分部定义。但是,编译器不考虑 sampleModule 内分部定义的提升。因此,它尝试编译两个名称均为 sampleClass 但具有不同限定路径的不同类。#t#
只有在两个分部定义的完全限定路径相同时,编译器才会对这两个分部定义进行合并。
建议
下面的建议提供了良好的编程做法。
***名称。 当您可以完全控制编程元素的命名时,在所有位置使用***名称始终是一个好办法。相同的名称需要额外的限定,并可能使代码难以阅读,还可能导致难以发现的错误和意外的结果。
完全限定。 当您在同一命名空间中使用模块和其他元素时,最安全的方法是对所有编程元素始终使用完全限定。如果某个模块成员的VB.NET类型提升失效,而您没有完全限定该成员,则无意中可能会访问另一个编程元素。