可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
Is it considered an acceptable practice to use Modules instead of Classes with Shared member functions in VB.NET?
I tend to avoid Modules, because they feel like leftover remains from Visual Basic 6.0 and don't really seem to fit in anymore. On the other hand, there doesn't seem to be much difference between using a Module and a Class with only Shared members. It's not that often that I really have much need for either, but sometimes there are situations where they present a simple solution.
I'm curious to hear whether you have any opinion or preferences one way or the other.
回答1:
Module
s are VB counterparts to C# static
classes. When your class is designed solely for helper functions and extension methods and you don't want to allow inheritance and instantiation, you use a Module
.
By the way, using Module
is not really subjective and it's not deprecated. Indeed you must use a Module
when it's appropriate. .NET Framework itself does it many times (System.Linq.Enumerable
, for instance). To declare an extension method, it's required to use Module
s.
回答2:
I think it's a good idea to keep avoiding modules unless you stick them into separate namespaces. Because in Intellisense methods in modules will be visible from everywhere in that namespace.
So instead of ModuleName.MyMethod()
you end up with MyMethod()
popups in anywhere and this kind of invalidates the encapsulation. (at least in the programming level).
That's why I always try to create Class with shared methods, seems so much better.
回答3:
Modules are by no means deprecated and are used heavily in the VB language. It's the only way for instance to implement an extension method in VB.Net.
There is one huge difference between Modules and Classes with Static Members. Any method defined on a Module is globally accessible as long as the Module is available in the current namespace. In effect a Module allows you to define global methods. This is something that a class with only shared members cannot do.
Here's a quick example that I use a lot when writing VB code that interops with raw COM interfaces.
Module Interop
Public Function Succeeded(ByVal hr as Integer) As Boolean
...
End Function
Public Function Failed(ByVal hr As Integer) As Boolean
...
End Function
End Module
Class SomeClass
Sub Foo()
Dim hr = CallSomeHrMethod()
if Succeeded(hr) then
..
End If
End Sub
End Class
回答4:
It is acceptable to use Module
. Module
is not used as a replacement for Class
. Module
serves its own purpose. The purpose of Module
is to use as a container for
- extension methods,
- variables that are not specific to any
Class
, or
- variables that do not fit properly in any
Class
.
Module
is not like a Class
since you cannot
- inherit from a
Module
,
- implement an
Interface
with a Module
,
- nor create an instance of a
Module
.
Anything inside a Module
can be directly accessed within the Module
assembly without referring to the Module
by its name. By default, the access level for a Module
is Friend
.
回答5:
Classes
- classes can be instantiated as objects
- Object data exists separately for each instantiated object.
- classes can implement interfaces.
- Members defined within a class are scoped within a specific instance of the class and exist only for the lifetime of the object.
- To access class members from outside a class, you must use fully qualified names in the format of Object.Member.
Modules
- Modules cannot be instantiated as objects,Because there is only one copy of a standard module's data, when one part of your program changes a public variable in a standard module, it will be visible to the entire program.
- Members declared within a module are publicly accessible by default.
- It can be accessed by any code that can access the module.
- This means that variables in a standard module are effectively global variables because they are visible from anywhere in your project, and they exist for the life of the program.
回答6:
When one of my VB.NET classes has all shared members I either convert it to a Module with a matching (or otherwise appropriate) namespace or I make the class not inheritable and not constructable:
Public NotInheritable Class MyClass1
Private Sub New()
'Contains only shared members.
'Private constructor means the class cannot be instantiated.
End Sub
End Class
回答7:
Modules are fine for storing enums and some global variables, constants and shared functions. its very good thing and I often use it. Declared variables are visible acros entire project.
回答8:
You must use a Module (rather than a Class) if you're creating Extension methods. In VB.NET I'm not aware of another option.
Being resistant to Modules myself, I just spent a worthless couple of hours trying to work out how to add some boilerplate code to resolve embedded assemblies in one, only to find out that Sub New()
(Module) and Shared Sub New()
(Class) are equivalent. (I didn't even know there was a callable Sub New()
in a Module!)
So I just threw the EmbeddedAssembly.Load
and AddHandler AppDomain.CurrentDomain.AssemblyResolve
lines in there and Bob became my uncle.
Addendum: I haven't checked it out 100% yet, but I have an inkling that Sub New()
runs in a different order in a Module than a Class, just going by the fact that I had to move some declarations to inside methods from outside to avoid errors.