VB.NET中的类与模块

VB.NET中的类与模块,vb.net,Vb.net,在VB.NET中使用模块而不是具有共享成员函数的类是否被认为是一种可接受的做法 我倾向于避免使用模块,因为它们感觉像是VisualBasic6.0遗留下来的东西,似乎不再适合。另一方面,使用模块和只包含共享成员的类之间似乎没有太大区别。这两种方法我都不太需要,但有时它们会提供一个简单的解决方案 我很好奇你是否有任何意见或偏好。模块s是C#静态类的VB对应项。当您的类仅为帮助函数和扩展方法而设计时,不想允许继承和实例化,您可以使用模块 顺便说一句,使用模块并不是很主观,而且也不受欢迎。实际上,您必

在VB.NET中使用模块而不是具有共享成员函数的类是否被认为是一种可接受的做法

我倾向于避免使用模块,因为它们感觉像是VisualBasic6.0遗留下来的东西,似乎不再适合。另一方面,使用模块和只包含共享成员的类之间似乎没有太大区别。这两种方法我都不太需要,但有时它们会提供一个简单的解决方案


我很好奇你是否有任何意见或偏好。

模块
s是C#
静态
类的VB对应项。当您的类仅为帮助函数和扩展方法而设计时,不想允许继承和实例化,您可以使用
模块


顺便说一句,使用
模块
并不是很主观,而且也不受欢迎。实际上,您必须在适当的时候使用
模块。NET框架本身多次这样做(例如,
System.Linq.Enumerable
)。要声明扩展方法,需要使用
Module
s.

我认为避免使用模块是个好主意,除非您将模块粘贴到单独的名称空间中。因为在Intellisense中,模块中的方法将在该命名空间中的任何位置都可见

因此,您不必使用
ModuleName.MyMethod()
而是在任意位置出现
MyMethod()
弹出窗口,这样会使封装无效。(至少在编程级别)


这就是为什么我总是尝试使用共享方法创建类,这似乎要好得多。

模块绝不是不受欢迎的,并且在VB语言中大量使用。例如,这是在VB.Net中实现扩展方法的唯一方法

模块和具有静态成员的类之间有一个巨大的区别。只要模块在当前命名空间中可用,在模块上定义的任何方法都是全局可访问的。实际上,模块允许您定义全局方法。这是只有共享成员的类无法做到的

下面是一个我在编写与原始COM接口交互的VB代码时经常使用的快速示例

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

当我的某个VB.NET类拥有所有共享成员时,我要么将其转换为具有匹配(或其他适当)命名空间的模块,要么使该类不可继承且不可构造:

Public NotInheritable Class MyClass1

   Private Sub New()
      'Contains only shared members.
      'Private constructor means the class cannot be instantiated.
   End Sub

End Class

可以使用
模块
<代码>模块
不用作
的替代品<代码>模块
有自己的用途。
模块
的用途是用作

  • 扩展方法
  • 不特定于任何
    类的变量,或
  • 不适合任何
    类的变量
模块
不像
,因为您不能

  • 模块继承
  • 使用
    模块实现
    接口
  • 也不创建
    模块的实例

模块
中的任何内容都可以在
模块
程序集中直接访问,而无需通过名称引用
模块
。默认情况下,
模块
的访问级别为
朋友

  • 类可以实例化为对象
  • 每个实例化对象的对象数据分别存在
  • 类可以实现接口
  • 在类中定义的成员在类的特定实例中的作用域为,并且仅在对象的生存期内存在
  • 要从类外部访问类成员,必须使用Object.Member格式的完全限定名
模块

  • 模块不能实例化为对象,因为标准模块的数据只有一个副本,当程序的一部分更改标准模块中的公共变量时,整个程序都可以看到它
  • 默认情况下,模块中声明的成员可公开访问
  • 任何可以访问模块的代码都可以访问它
  • 这意味着标准模块中的变量实际上是全局变量,因为它们在项目中的任何位置都可见,并且在程序的生命周期中都存在

模块可用于存储枚举和一些全局变量、常量和共享函数。这是一件非常好的事情,我经常使用它。声明的变量在整个项目中都是可见的。

如果要创建扩展方法,必须使用模块(而不是类)。在VB.NET中,我不知道还有其他选项

出于对模块的抵制,我花了几个毫无价值的小时试图研究如何添加一些样板代码来解析其中的嵌入式程序集,结果发现
Sub-New()
(模块)和
Shared-Sub-New()
(类)是等价的。(我甚至不知道模块中有一个可调用的
Sub New()

因此,我在那里抛出了
EmbeddedAssembly.Load
AddHandler AppDomain.CurrentDomain.AssemblyResolve
行,Bob成了我的叔叔


附录:我还没有100%地检查出来,但我有一个线索,
Sub New()
在模块中的运行顺序与类不同,只是因为我必须从外部将一些声明移动到内部方法以避免错误。

非常正确,尽管我可以使用私有构造函数来阻止实例化和NotInheritable修饰符。比普通的旧模块稍微难看一点,但具有相同的效果。比