Shared (Visual Basic)

指定一个或多个所声明的编程元素与整个类或结构关联,不与类或结构的特定实例关联。

何时使用共享

共享类或结构的成员使其可用于每个实例,而不是非共享,其中每个实例都保留其自己的副本。 例如,如果将变量的值应用于整个应用程序,则共享会很有用。 如果将该变量声明为 Shared,则所有实例都将访问相同的存储位置,并且如果一个实例更改该变量的值,则所有实例都将访问更新的值。

共享不会更改成员的访问级别。 例如,类成员可以是共享和专用(只能在类内访问)或非共享和公共。 有关详细信息,请参阅 Visual Basic 中的访问级别

规则

  • 声明上下文。 只能在模块级别使用 Shared。 这意味着 Shared 元素的声明上下文必须是类或结构,并且不能是源文件、命名空间或过程。

  • 组合修饰符。 不能在同一声明中同时指定 SharedOverridesOverridableNotOverridableMustOverrideStatic

  • 访问。 通过使用共享元素的类或结构(不是共享元素特定类或结构实例的变量名称)限定共享元素,从而访问该共享元素。 甚至不必创建类或结构的实例即可访问其共享成员。

    以下示例调用 Double 结构公开的共享过程 IsNaN

    If Double.IsNaN(result) Then Console.WriteLine("Result is mathematically undefined.")
    
  • 隐式共享。 不能在 Const 语句中使用 Shared 修饰符,但常量是隐式共享的。 同样,不能将模块或接口的成员声明为 Shared,但它们是隐式共享的。

行为

  • 存储。 无论创建多少类或结构的实例,共享变量或事件也只会存储在内存中一次。 同样,共享过程或属性仅保存一组局部变量。

  • 通过实例变量访问。 可以通过使用包含共享元素特定类或结构实例的变量的名称来访问该共享元素。 虽然这通常按预期工作,但编译器会生成一条警告消息,并通过类或结构名称(而不是变量)进行访问。

  • 通过实例表达式访问。 如果通过返回类或结构实例的表达式访问共享元素,则编译器将通过类或结构名称(而不是计算表达式)进行访问。 如果你希望表达式执行其他操作以及返回实例,则此访问会产生意外结果。 下面的示例阐释了这种情况。

    Sub Main()
        ' The following line is the preferred way to access Total.
        ShareTotal.Total = 10
    
        ' The following line generates a compiler warning message and
        ' accesses total through class ShareTotal instead of through
        ' the variable instanceVar. This works as expected and adds
        ' 100 to Total.
        Dim instanceVar As New ShareTotal
        instanceVar.Total += 100
    
        ' The following line generates a compiler warning message and
        ' accesses total through class ShareTotal instead of calling
        ' ReturnClass(). This adds 1000 to total but does not work as
        ' expected, because the WriteLine in ReturnClass() does not run.
        Console.WriteLine("Value of total is " & CStr(ShareTotal.Total))
        ReturnClass().Total += 1000
    End Sub
    
    Public Function ReturnClass() As ShareTotal
        Console.WriteLine("Function ReturnClass() called")
        Return New ShareTotal
    End Function
    
    Public Class ShareTotal
        Public Shared Property Total As Integer
    End Class
    

    在前面的示例中,编译器会在代码通过实例访问共享属性 Total 时生成警告消息。 在每种情况下,都会通过类 ShareTotal 直接进行访问,而不使用任何实例。 在对过程 ReturnClass 的预期调用的情况下,这意味着甚至不会生成对 ReturnClass 的调用,因此不会执行显示“Function ReturnClass() called”的其他操作。

Shared 修饰符可用于下面的上下文中:

另请参阅