简体   繁体   English

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

[英]Why does VB allow declaring object of a static type?

A client has a variable declared using a static type - similar to the following test (which compiles in VB): 客户端具有使用静态类型声明的变量 - 类似于以下测试(在VB中编译):

Dim test As System.IO.File

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会对这个声明有问题(就像C#那样),但是因为它没有我认为有一些深奥的VB-ish目的呢?

There is actually no such thing as a Shared class in VB.NET. 在VB.NET中实际上没有 Shared这样的东西 ( Shared is the VB.NET keyword for what we know and love as static in C#). Shared是我们所知道的并且喜欢C#中的static的VB.NET关键字)。 Only member variables (fields), events, functions/subs, properties, and operators can be marked Shared . 只有成员变量(字段),事件,函数/子,属性和运算符才能标记为“ 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.) (跨调用保留其值的局部变量都没有标注Shared ,而是Static 。在CLR本身并不支持这些也不认为C#,但VB.NET编译器生成所需的额外的代码,使其工作。)

There are two workarounds to effect the same result as a static class in VB.NET: 有两种解决方法可以在VB.NET中实现与静态类相同的结果:

  1. Create a Module . 创建一个Module Practically, this is the same as a static class. 实际上,这与静态类相同。 Indeed, from an IL perspective, they are identical. 实际上,从IL的角度来看,它们是相同的。 However, modules are treated slightly differently in the VB.NET language proper. 但是,在VB.NET语言中,模块的处理方式略有不同。 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) 模块的概念继承自传统的基于COM的VB(实际上,它们比它更老,可以追溯到早期版本的BASIC)

    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 . 如果您熟悉C ++或类似语言,则模块类似于命名空间,除了通过Microsoft.VisualBasic.CompilerServices.StandardModule属性将模块中定义的所有函数提升到外部作用域(封闭命名空间)之外。 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 ( eg , MyModule.MyFunction(...) ). 但是,您仍然(通常应该更喜欢)使用完全限定引用( 例如MyModule.MyFunction(...) )来调用模块中定义的函数。

  2. 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 . 创建一个NotInheritable类(相当于C#的abstract关键字的VB.NET),给它一个空的Private构造函数,并将其所有方法标记为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. 因此,编译器不强制执行不能声明该类的实例的规则,因为从编译器的角度来看,该类与任何其他类没有区别。

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. 由于.NET BCL是用C#编写的,因此它使用选项2.所有标记为static的类都是VB.NET中具有Shared成员函数和私有构造函数的NotInheritable类。 For example, the declaration of System.IO.File appears as follows to VB.NET: 例如, 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

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 . 当然,它们永远不会被分配一个值,所以它们总是等于Nothing ( TypeOf(test) Is Nothing will return True , in this case, as will test Is Nothing , and TypeName(test) will return Nothing ). TypeOf(test) Is Nothing将返回True ,在这种情况下,将test Is Nothing ,而TypeName(test)将返回Nothing )。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么将 CosmosClient 声明为私有静态可以解决我的问题? - Why does declaring CosmosClient as private static solve my problem? 为什么编译器允许在静态上下文中创建非静态类的对象? - Why the compiler allow to create an object of non static class in static context? 为什么将委托声明为静态导致编译器错误“修饰符'静态'对此项无效”? - Why does declaring a delegate as static cause compiler error “The modifier 'static' is not valid for this item”? 为什么魔术会锁定System.Object的实例而不是锁定特定的实例类型? - Why magic does an locking an instance of System.Object allow differently than locking a specific instance type? 为什么vb.net允许将类名用作参数名? - Why does vb.net allow class names to be parameter names? 为什么ParameterizedThreadStart只允许对象参数? - Why Does ParameterizedThreadStart Only Allow Object Parameter? 为什么C#不允许在同一行上使用const和static? - Why does C# not allow const and static on the same line? 为什么C#不允许在方法中将变量声明为静态? - Why does C# not allow variables to be declared static in methods? 当类型为“未知”时声明对象 - Declaring an object when type is “unknown” 在C#中声明静态类型的成员 - Declaring a member of static type in c#
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM