在VB.NET中将一个类标记为静态的

100

最近在一个问题和相应的答案中刚刚提到,你不能从静态类继承。如何在VB.NET中执行与静态类相关的规则?由于框架在C#和VB之间是兼容的,因此应该有一种标记类为静态的方法,但似乎并没有。

5个回答

136

模块 == 静态类

如果您只需要一个不能被继承的类,请使用NotInheritable类; 但它不会是静态/共享的。您可以将所有方法、属性和成员标记为Shared,但这不严格等同于C#中的静态类,因为编译器不会强制执行。

如果您真的想要VB.Net中与C#静态类等效的类,请使用Module。它不能被继承,所有成员、属性和方法都是静态/共享的。


2
我撤回之前的评论。我在反编译器中查看了一个模块,发现它是被封闭的。 - MagicKat
30
你是VBer吗? 一个模块就像一个命名空间。 VB的所有函数都从模块中导入,并在全局范围内使用。 我认为,VB中的静态类不是一个模块,它具有不同的行为。 如果你想要在VB中实现静态类的行为,你应该使用NotInheritable并声明所有成员为“Shared”,就像在C#的静态类中一样,它们会表现得相同。 而模块则不然。 - Shimmy Weitzhandler
2
@Shimmy,我不知道为什么之前错过了这条评论,但你是错误的。看一下生成的IL代码,模块和静态类得到完全相同的处理。VB只是为旧标准函数做额外的工作,使它们出现在全局范围内。 - Joel Coehoorn
2
@JoelCoehoorn 模块 ≈≈ 静态类,因为模块必须直接在命名空间中声明。这意味着不能在模块或类中声明模块。 - LosManos
23
了解模块和静态类最终生成相同的IL代码是有好处的,但VB还将模块的成员提升到包含命名空间中。这种“提升”的方面是模块和静态类在实际使用中不同的地方,在我看来,这是一个巨大的区别。我更喜欢“NotInheritable-空私有构造函数-所有成员共享”的解决方案,因为只能通过类访问成员,这是更正确的行为,如果你想获得静态类的等效性。虽然生成的IL代码可能不同,但这基本上是学术问题。 - misha256
显示剩余5条评论

64

快到了,你还需要防止实例化。

NotInheritable Class MyStaticClass

    ''' <summary>
    ''' Prevent instantiation.
    ''' </summary>
    Private Sub New()

    End Sub

    Public Shared Function MyMethod() As String

    End Function

End Class
  • Shared就像是静态类的方法。
  • NotInheritable就像是sealed。
  • Private New就像是静态类不能被实例化。

参见:
MSDN - 静态类和静态类成员


2
为什么这不是被接受的答案?感谢您提供的代码片段。 - ArcherBird

6

如果您只想创建一个无法继承的类,在C#中可以使用Sealed,在VB.Net中使用NotInheritable。

VB.Net中static的等价物是shared。


你可以将变量和功能标记为共享,就像在C#静态类中一样。 将其标记为NotInheritable会使其被封闭。 - Shimmy Weitzhandler

4

您可以在VB.NET中创建静态类。解决方案如下:

Friend NotInheritable Class DB
    Public Shared AGE As Integer = 20
End Class

AGE变量是公共静态的,您可以像这样在其他代码中使用它

 Dim myage As Integer = DB.AGE

Friend = 公共的,NotInheritable = 静态的。


7
朋友不等于公开,朋友等于内部。 - Altair
6
不可继承(NotInheritable)并不等同于静态(static),不可继承(NotInheritable)等同于密封(sealed)。 - Magnus
6
我的年龄不再是20岁(很遗憾)。 - Grim

2

从CLR的角度来看,C#的静态类只是一个"sealed"和"abstract"类。你不能创建实例,因为它是抽象的,也不能继承它,因为它是密封的。其余部分只是一些编译器的魔法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接