Type Promotion (Visual Basic)
Updated: July 20, 2015
For the latest documentation on Visual Studio 2017 RC, see Visual Studio 2017 RC Documentation.
When you declare a programming element in a module, Visual Basic promotes its scope to the namespace containing the module. This is known as type promotion.
The following example shows a skeleton definition of a module and two members of that module.
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, programming elements declared at module level are promoted to
projNamespace. In the preceding example,
innerClass are promoted, but
numberSub is not, because it is not declared at module level.
The effect of type promotion is that a qualification string does not need to include the module name. The following example makes two calls to the procedure in the preceding example.
Sub usePromotion() projNamespace.projModule.innerClass.numberSub(projNamespace.projModule.basicEnum.one) projNamespace.innerClass.numberSub(projNamespace.basicEnum.two) End Sub
In the preceding example, the first call uses complete qualification strings. However, this is not necessary because of type promotion. The second call also accesses the module's members without including
projModule in the qualification strings.
If the namespace already has a member with the same name as a module member, type promotion is defeated for that module member. The following example shows a skeleton definition of an enumeration and a module within the same namespace.
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
In the preceding example, Visual Basic cannot promote class
thisNameSpace because there is already an enumeration with the same name at namespace level. To access
abcSub, you must use the full qualification string
thisNamespace.thisModule.abc.abcSub. However, class
xyz is still promoted, and you can access
xyzSub with the shorter qualification string
If a class or structure inside a module uses the Partial keyword, type promotion is automatically defeated for that class or structure, whether or not the namespace has a member with the same name. Other elements in the module are still eligible for type promotion.
Consequences. Defeat of type promotion of a partial definition can cause unexpected results and even compiler errors. The following example shows skeleton partial definitions of a class, one of which is inside a module.
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
In the preceding example, the developer might expect the compiler to merge the two partial definitions of
sampleClass. However, the compiler does not consider promotion for the partial definition inside
sampleModule. As a result, it attempts to compile two separate and distinct classes, both named
sampleClass but with different qualification paths.
The compiler merges partial definitions only when their fully qualified paths are identical.
The following recommendations represent good programming practice.
Unique Names. When you have full control over the naming of programming elements, it is always a good idea to use unique names everywhere. Identical names require extra qualification and can make your code harder to read. They can also lead to subtle errors and unexpected results.
Full Qualification. When you are working with modules and other elements in the same namespace, the safest approach is to always use full qualification for all programming elements. If type promotion is defeated for a module member and you do not fully qualify that member, you could inadvertently access a different programming element.