Visual Basic 中的生存期

已声明元素的的生存期是指变量可供使用的时间。 变量是具有生存期的唯一元素。 为此,编译器将过程参数和函数返回作为变量的特殊情况处理。 变量的生存期表示它可以保存一个值的时间范围。 它的值可以在其生存期内更改,但它始终保存一些值。

不同的生存期

成员变量(在模块级,在任何过程之外声明)通常与声明它的元素具有相同的生存期。 在类或结构中声明的非共享变量作为为声明它的类或结构的每个实例的单独副本存在。 每个此类变量与实例的生存期相同。 但是,Shared 变量只有单个生存期,即应用程序运行时的整个生存期。

局部变量(在过程中声明)仅在其声明的过程运行时才存在。 这同样适用于该过程的参数和任何函数返回。 但是,如果该过程调用其他过程,则在调用的过程正在运行时,局部变量将保留其值。

生存期的开始

当控件进入声明局部变量的过程时,局部变量的生存期就开始了。 当过程开始运行时,每个局部变量都被初始化为其数据类型的默认值。 当过程遇到指定初始值的 Dim 语句时,它将这些变量设置为这些值,即使你的代码已经为它们分配了其他值。

结构变量的每个成员都初始化为一个单独的变量。 同样,数组变量的每个元素都单独初始化。

在过程内部的块中声明的变量(如 For 循环)在进入该过程时进行初始化。 无论代码是否执行块,这些初始化都将生效。

生存期结束

过程终止后,不会保留其局部变量的值,Visual Basic 将回收其内存。 下一次调用该过程时,将重新创建并重新初始化其所有局部变量。

当类或结构的实例终止时,其非共享变量将丢失其内存和值。 类或结构的每个新实例都创建并重新初始化其非共享变量。 但是,会保留变量 Shared,直到应用程序停止运行。

生存期扩展

如果使用 Static 关键字声明局部变量,则其生存期长于其过程的执行时间。 下表显示了过程声明如何确定 Static 变量的存在时间。

过程位置和共享 静态变量生存期开始 静态变量生存期结束
在模块中(默认共享) 第一次调用该过程时 当应用程序停止运行时
在类中,Shared(过程不是实例成员) 第一次在特定实例或类或结构名称本身上调用该过程 当应用程序停止运行时
在类的实例中,而不是Shared(过程是实例成员) 第一次在特定实例上调用该过程时 释放实例以进行垃圾回收 (GC) 时

相同名称的静态变量

可以在多个过程中声明具有相同名称的静态变量。 如果这样做,Visual Basic 编译器会将每个此类变量视为一个单独的元素。 其中一个变量的初始化不会影响其他变量的值。 如果使用一组重载定义过程,并在每个重载中使用相同名称声明静态变量,则这一点同样适用。

包含静态变量的元素

可以在类中声明静态局部变量,即在类的过程中声明静态局部变量。 但是,不能在结构中将静态局部变量声明为结构成员或该结构中过程的局部变量。

示例

说明

下面的示例使用 Static 关键字声明一个变量。 (请注意,当 Dim 语句使用了如 Static 的修饰符时,不需要 Dim 关键字。)

代码

Function runningTotal(ByVal num As Integer) As Integer
    Static applesSold As Integer
    applesSold = applesSold + num
    Return applesSold
End Function

注释

在前面的示例中,变量 applesSold 将在该过程 runningTotal 返回给调用代码后继续存在。 下次调用 runningTotal 时,applesSold 保留之前计算的值。

如果在未使用 Static 的情况下声明了 applesSold,则在调用 runningTotal 时不会保留之前的累计值。 下一次调用 runningTotal 时, applesSold 将重新创建并将其初始化为 0,runningTotal 将仅返回调用它时使用的相同值。

编译代码

可以将静态局部变量的值初始化为其声明的一部分。 如果将数组声明为 Static,则可以将其级别(维数)、每个维的长度以及各个元素的值初始化。

安全性

在前面的示例中,可以通过在模块级别声明 applesSold 来生成相同的生存期。 但是,如果以这种方式更改了变量的作用域,则该过程将不再具有对该变量的独占访问权。 由于其他过程可能会访问 applesSold 并更改其值,因此,运行总计可能不可靠,并且代码可能更难以维护。

请参阅