In case you never programmed in VB6, you would be wondering what a module is. Its a convenience offered by VB6 to write functions (you can have variables in a module too). You can access the functions (or variables) in a module just like calling global functions (or variables) i.e. by omitting the module name as prefix.
Please note that the CLR has no notion of a module. Then how come we still have modules in VB.NET? In a moment we will see how the VB.NET team manages to keep the CLR as well as the VB6 programmer happy.
Let us create a module as follows :
Public Module TestModule
Public Sub TestFunction()
Console.WriteLine(“Test function of TestModule called !”)
End Sub
End Module
– TestModule.TestFunction()
– TestFunction
Here is the declaration of our TestModule in IL :
.class public auto ansi sealed TestModule
extends [mscorlib]System.Object
{
}
– all members are implicitly Shared (this can be verified by looking at the IL for the function). You cannot explicitly declare a member as Shared, it will result in a compilation error.
– you cannot create an instance of this class.
But if you think about it again, the class is NotInheritable (sealed) and you cant create an instance of it either, which means that the class should be MustInherit (abstract). A class cannot be NotInheritable and MustInherit at the same time, but then how do we explain this apparent paradox ? The compiler pulls a trick here. The class isnt made abstract, instead the compiler just “forgets” to add a default constructor. We know that if we dont define any constructor for a class, the compiler will automatically add one for you (the default constructor). In the case of Modules, VB.NET wont allow you to write a constructor manually. Neither will it add a constructor automatically for you when it compiles the module. It is the absence of the constructor that prevents the creation of an instance of a Module.
If you are a C# programmer, you would have but one doubt – how can you use a VB.NET Module from C#?
If you expose a Module from a VB.NET library and use it in a C# project, we wouldnt have any problem if we just call the functions like we are calling static functions declared in a class. We are forced to use the Type prefix (the name of the Module) unlike in VB.NET where we could simply invoke the function by omitting the module name. We cant create an instance of the the Module, just like in VB.NET.
If you think that all is well with Modules, then you havent heard the full story. If we have 2 modules in your project and both contain functions with same name and signature, then we are forced to prefix the Module name to resolve the ambiguity. This issue is caught by the compiler and is not much of a problem. But you we could get in trouble if there are two functions of same name and signature in two modules which reside in different assemblies. The compiler would look in the modules of the current assembly for a match before it would look in external assemblies. This makes perfect sense but can catch us off gaurd if we arent aware of the possiblity, especially if multiple developers work on the same module. It would be better to prefix the Module name to prevent such problems – we might end up calling a function in a Module in the local assembly when we really wanted to call a function residing in a Module in an outside assembly.