为什么VB允许声明静态类型的对象?

Dav*_*jas 3 c# vb.net

客户端具有使用静态类型声明的变量 - 类似于以下测试(在VB中编译):

Dim test As System.IO.File
Run Code Online (Sandbox Code Playgroud)

这样做的目的是什么?在我的客户端代码中,此变量未在任何地方引用,因此我无法遵循任何使用模式.我原以为VB会对这个声明产生问题(就像C#那样),但是因为它没有我认为有一些深奥的VB-ish目的呢?

Cod*_*ray 7

其实是有没有这样的事情作为一个Shared在VB.NET类.(Shared是我们static在C#中所知道和喜爱的VB.NET关键字).只能标记成员变量(字段),事件,函数/子,属性和运算符Shared.(没有标记在调用中保留其值的局部变量Shared,而是标记Static.CLR本身不支持这些,C#也不支持,但VB.NET编译器会发出使其工作所需的其他代码.)

有两种解决方法可以在VB.NET中实现与静态类相同的结果:

  1. 创建一个Module.实际上,这与静态类相同.实际上,从IL的角度来看,它们是相同的.但是,在VB.NET语言中,模块的处理方式略有不同.模块的概念继承自传统的基于COM的VB(实际上,它们比它更老,可以追溯到早期版本的BASIC)

    如果您熟悉C++或类似语言,则模块类似于命名空间,除了模块中定义的所有函数都通过Microsoft.VisualBasic.CompilerServices.StandardModule属性提升到外部作用域(封闭命名空间).模块永远不会被视为类,因此对模块的任何声明或引用都是非法的.但是,您仍然可以(通常更喜欢)使用完全限定引用(例如,MyModule.MyFunction(...))调用模块中定义的函数.

  2. 创建一个NotInheritable类(VB.NET相当于C#的abstract关键字),给它一个空的Private构造函数,并将其所有方法标记为Shared.请注意,类本身实际上并不是共享/静态 - 只是构成该类的各个函数.因此,编译器不强制执行不能声明该类的实例的规则,因为从编译器的角度来看,该类与任何其他类没有区别.

由于.NET BCL是用C#编写的,因此它使用选项2.所有标记staticNotInheritable类都只是VB.NET中具有Shared成员函数和私有构造函数的类.例如,System.IO.FileVB.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
Run Code Online (Sandbox Code Playgroud)

请注意,由于仅禁止实例化(通过使构造函数为私有),编译器仍允许您声明该类类型的空变量.当然,它们永远不会被赋予价值,所以它们总是等于Nothing.(TypeOf(test) Is Nothing将返回True,在这种情况下,意志test Is NothingTypeName(test)返回Nothing).

  • @CodyGray,总的来说是一个很好的解释+1,但是`"(所以MyModule.MyFunction是非法的.你只需要调用MyFunction.)"`是不正确的.实际上,建议使用完全限定版本.请参阅:[类型促销(Visual Basic)](https://msdn.microsoft.com/en-us/library/xz7s1h1x.aspx).在一个扭曲的笔记中,VB中支持类型的促销愚蠢,因为你可以使用任何.Net语言编译的类继承这个_feature_以便在VB中使用. (2认同)