I can read a lot over the Internet that VB.Net Modules are the same thing as c#.Net Static Classes. I can also read that something close to a Static Class
is a class which would look like this:
'NotInheritable so that no other class can be derived from it
Public NotInheritable Class MyAlmostStaticClass
'Private Creator so that it cannot be instantiated
Private Sub New()
End Sub
'Shared Members
Public Shared Function MyStaticFunction() as String
Return "Something"
End Function
End Class
I find this code heavy to draft, and to read. I would be much more confortable just using a Module
like this:
Public Module MyEquivalentStaticClass
Public Function MyStaticFunction() as String
Return "Something"
End Function
End Module
However, with a Module
you loose one level of Namespace
hierarchy, and the following 3 statements are equal:
'Call through the Class Name is compulsory
Dim MyVar as String = Global.MyProject.MyAlmostStaticClass.MyStaticFunction()
'Call through the Module Name is OPTIONAL
Dim MyVar as String = Global.MyProject.MyEquivalentStaticClass.MyStaticFunction()
Dim MyVar as String = Global.MyProject.MyStaticFunction()
I find this very inconvenient and this either pollutes the Intelisense, or forces me to create additionnal levels of Namespace
, which then means more Module
declaration, i.e., more Intelisense pollution.
Is there a workaround or is this the price to pay if you want to avoid the heavy SharedMembers-NotInheritable-PrivateNew Class
declaration?
Additionnal references include the very good post by Cody Gray: https://stackoverflow.com/a/39256196/10794555
The main difference between classes and modules is that classes can be instantiated as objects while standard modules cannot.
A class is a type. You can use this type like any other type ( String , Integer , Date , FileInfo ...) to declare variables, parameters, properties, and function return types. Whereas modules are static. I.e. Data stored in a module exists exactly once.
No, there is no exact equivalent to a C# static class in VB.NET. It would be nice if VB had the ability to add the Shared
modifier to a class declaration, like this:
Public Shared Class Test ' This won't work, so don't try it
' Compiler only allows shared members in here
End Class
But, unfortunately, it does not. If you do that, the compiler gives you the following error:
Classes cannot be declared 'Shared'
That leaves us with the two options you listed:
Shared
members (without the safety of that rule being enforced by the compiler), or Module
, which makes everything Shared
, even though you don't explicitly say so via the Shared
modifierAs you said, many people don't like the loss of the class name being required, as a sort-of extra namespace layer, so they prefer the Class
with only Shared
members over the Module
. But, that's a matter of preference.
It's worth noting that, while you don't have to specify the module name everywhere you call its members, you can always do so if you wish:
MyModule.MyMethod()
While a "SharedMembers-NotInheritable-PrivateNew Class", as you so eloquently called it, is the closest approximation to a static class, it's only functionally equivalent. If you use reflection, you'll see that the attributes of the type are not the same. For instance, in VB:
Module MyModule
Public Sub Main()
Dim t As Type = GetType(MyClass)
End Sub
End Module
Public NotInheritable Class MyClass
Private Sub New()
End Sub
Public Shared Sub MyMethod()
End Sub
End Class
If you take a look at t.Attributes
, you'll see that it equals Public Or Sealed
. So the MyClass
type is both sealed (NotInheritable
) and public. However, if you do this in C#:
class Program
{
static void Main(string[] args)
{
Type t = typeof(Test);
}
}
public static class MyClass
{
public static void MyMethod()
{ }
}
And you inspect the t.Attributes
again, this time, the value is Public | Abstract | Sealed | BeforeFieldInit
. That's not the same. Since you can't declare a class in VB as both NotInheritable
and MustInherit
at the same time, you have no chance of exactly duplicating that thing. So, while they more-or-less are equivalent, the attributes of the types are different. Now, just for fun, let's try this:
Module MyModule
Public Sub Main()
Dim t As Type = GetType(MyModule)
End Sub
End Module
Now, the t.Attributes
for the module are Sealed
. That's it. Just Sealed
. So that's not the same either. The only way to get a true static class in VB (meaning, the type has the same attributes when inspected via reflection) is to write it in a C# class library, and then reference the library in VB.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With