gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-30 14:07:37 25 4
gpt4 key购买 nike

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

Dim test As System.IO.File

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

最佳答案

在 VB.NET 中实际上没有Shared 类。 (Shared 是 VB.NET 关键字,代表我们所熟知和喜爱的 C# 中的 static)。只有成员变量(字段)、事件、函数/子、属性和运算符可以标记为Shared。 (跨调用保留其值的局部变量未标记为 Shared,而是标记为 Static。CLR 本身不支持这些,C# 也不支持,但 VB.NET编译器发出使其工作所需的附加代码。)

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

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

    如果您熟悉 C++ 或类似语言,模块类似于命名空间,只是模块中定义的所有函数都通过 Microsoft.VisualBasic.CompilerServices.StandardModule attribute 提升到外部作用域(封闭命名空间)。 .模块永远不能像类一样对待,因此对模块的任何声明或引用都是非法的。但是,您仍然可以(并且通常应该更喜欢)使用完全限定的引用调用模块中定义的函数(例如MyModule.MyFunction(...) ).

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

由于 .NET BCL 是用 C# 编写的,因此它使用选项 2。所有标记为 static 的类在 VB.NET 中都是简单的 NotInheritable 类,带有 共享 成员函数和私有(private)构造函数。例如,System.IO.File 的声明在 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

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

关于c# - 为什么 VB 允许声明静态类型的对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39255394/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com