A client has a variable declared using a static type - similar to the following test (which compiles in VB):
Dim test As System.IO.File
What is the purpose of this? In my client's code, this variable was not referenced anywhere so I couldn't follow any usage pattern. I would have expected that VB would have a problem with this declaration (as C# does), but since it doesn't I assume that there is some esoteric VB-ish purpose to this?
答案 0 :(得分:7)
There is actually no such thing as a Shared
class in VB.NET. (Shared
is the VB.NET keyword for what we know and love as static
in C#). Only member variables (fields), events, functions/subs, properties, and operators can be marked Shared
. (Local variables that retain their values across invocations are not marked Shared
, but rather Static
. The CLR doesn't natively support these and neither does C#, but the VB.NET compiler emits the additional code necessary to make it work.)
There are two workarounds to effect the same result as a static class in VB.NET:
Create a Module
. Practically, this is the same as a static class. Indeed, from an IL perspective, they are identical. However, modules are treated slightly differently in the VB.NET language proper. The concept of modules was inherited from legacy COM-based VB (actually, they are much older than that, going back to early versions of BASIC)
If you're familiar with C++ or similar languages, a module is akin to a namespace, except that all of the functions defined in a module are promoted into the outer scope (enclosing namespace), via the Microsoft.VisualBasic.CompilerServices.StandardModule
attribute. A module can never be treated like a class, so any declarations of or references to a module are illegal. However, you can still (and should generally prefer) to call a function defined in a module using a fully-qualified reference (e.g., MyModule.MyFunction(...)
).
Create a NotInheritable
class (VB.NET equivalent of C#'s abstract
keyword), give it an empty Private
constructor, and mark all of its methods as Shared
. Note that the class itself is not actually shared/static—just the individual functions that make up that class. The compiler therefore does not enforce the rule that an instance of that class cannot be declared, because from the compiler's perspective, the class is no different than any other class.
Since the .NET BCL was written in C#, it uses option 2. All classes that were marked static
are simply NotInheritable
classes in VB.NET with Shared
member functions and private constructors. For example, the declaration of System.IO.File
appears as follows to VB.NET:
Public NotInheritable Class File
Inherits System.Object
' Contains Shared methods, e.g.:
Public Shared Sub Copy(sourceFileName As String, destFileName As String)
' implementation
End Sub
' private constructor to prevent instantiation
Private Sub New()
End Sub
End Class
Note that since only instantiation is prohibited (via making the constructor private), the compiler still allows you to declare empty variables of that class type. They can never be assigned a value, of course, so they will always be equal to Nothing
. (TypeOf(test) Is Nothing
will return True
, in this case, as will test Is Nothing
, and TypeName(test)
will return Nothing
).