为什么 VB 允许声明静态类型的对象? [英] Why does VB allow declaring object of a static type?

查看:33
本文介绍了为什么 VB 允许声明静态类型的对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

A client has a variable declared using a static type - similar to the following test (which compiles in VB):

Dim test As System.IO.File

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

What is the purpose of this? In my client's code, this variable was not referenced anywhere so I couldn't follow any usage pattern. I would have expected that VB would have a problem with this declaration (as C# does), but since it doesn't I assume that there is some esoteric VB-ish purpose to this?

推荐答案

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

There is actually no such thing as a Shared class in VB.NET. (Shared is the VB.NET keyword for what we know and love as static in C#). Only member variables (fields), events, functions/subs, properties, and operators can be marked Shared. (Local variables that retain their values across invocations are not marked Shared, but rather Static. The CLR doesn't natively support these and neither does C#, but the VB.NET compiler emits the additional code necessary to make it work.)

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

There are two workarounds to effect the same result as a static class in VB.NET:

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

  1. Create a Module. Practically, this is the same as a static class. Indeed, from an IL perspective, they are identical. However, modules are treated slightly differently in the VB.NET language proper. The concept of modules was inherited from legacy COM-based VB (actually, they are much older than that, going back to early versions of BASIC)

如果您熟悉 C++ 或类似语言,模块类似于命名空间,除了模块中定义的所有函数都通过 Microsoft.VisualBasic.CompilerServices.StandardModule 属性.模块永远不能被视为类,因此对模块的任何声明或引用都是非法的.但是,您仍然可以(并且通常应该更喜欢)使用完全限定的引用(egMyModule.MyFunction(...))调用在模块中定义的函数).

If you're familiar with C++ or similar languages, a module is akin to a namespace, except that all of the functions defined in a module are promoted into the outer scope (enclosing namespace), via the Microsoft.VisualBasic.CompilerServices.StandardModule attribute. A module can never be treated like a class, so any declarations of or references to a module are illegal. However, you can still (and should generally prefer) to call a function defined in a module using a fully-qualified reference (e.g., MyModule.MyFunction(...)).

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

Create a NotInheritable class (VB.NET equivalent of C#'s abstract keyword), give it an empty Private constructor, and mark all of its methods as Shared. Note that the class itself is not actually shared/static—just the individual functions that make up that class. The compiler therefore does not enforce the rule that an instance of that class cannot be declared, because from the compiler's perspective, the class is no different than any other class.

由于 .NET BCL 是用 C# 编写的,所以它使用选项 2.所有标记为 static 的类在 VB.NET 中都只是 NotInheritable 类,带有 共享 成员函数和私有构造函数.例如,System.IO.File 的声明在 VB.NET 中显示如下:

Since the .NET BCL was written in C#, it uses option 2. All classes that were marked static are simply NotInheritable classes in VB.NET with Shared member functions and private constructors. For example, the declaration of System.IO.File appears as follows to 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

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

Note that since only instantiation is prohibited (via making the constructor private), the compiler still allows you to declare empty variables of that class type. They can never be assigned a value, of course, so they will always be equal to Nothing. (TypeOf(test) Is Nothing will return True, in this case, as will test Is Nothing, and TypeName(test) will return Nothing).

这篇关于为什么 VB 允许声明静态类型的对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆