Visual Basic 中的范围

已声明元素的范围是一组所有代码,这些代码可以在不限定其名称的情况下引用它,或者通过 Imports 语句(.NET 命名空间和类型)提供它。 元素的范围可以位于以下级别之一:

Level 说明
块范围 仅在声明它的代码块中可用
过程范围 可用于在其中声明它的过程内的所有代码
模块范围 可用于在其中声明它的模块、类或结构内的所有代码
命名空间范围 可用于在其中声明它的命名空间中的所有代码

这些范围级别从最窄的范围(块)到最宽的范围(命名空间),其中,最窄的范围表示可以引用元素且没有限定的最小的代码集。 有关详细信息,请参阅本页上的“范围级别”。

指定范围并定义变量

在声明元素时指定该元素的范围。 范围可能取决于以下因素:

  • 在其中声明元素的区域(块、过程、模块、类或结构)

  • 包含元素的声明的命名空间

  • 为元素声明的访问级别

定义名称相同但范围不同的变量时请谨慎,因为这样做可能会导致意外结果。 有关详细信息,请参阅 References to Declared Elements

范围级别

编程元素在声明它的整个区域都可用。 同一区域中的所有代码可以引用元素且不限定其名称。

块范围

块是一组包含在启动和终止声明语句中的语句,如下所示:

  • DoLoop

  • For [Each] 和 Next

  • IfEnd If

  • SelectEnd Select

  • SyncLockEnd SyncLock

  • TryEnd Try

  • WhileEnd While

  • WithEnd With

如果在块中声明变量,则只能在该块内使用它。 在下面的示例中,cube 整数变量的范围是 IfEnd If 之间的块,当执行从块中传递出来时,你无法再引用 cube

If n < 1291 Then
    Dim cube As Integer
    cube = n ^ 3
End If

备注

即使一个变量的范围仅限于块,其生存期仍为整个过程的生存期。 如果在过程中多次输入块,则每个块变量将保留其以前的值。 为了避免在这种情况下出现意外结果,在块的开头初始化块变量是一个明智之举。

过程范围

在过程中声明的元素在该过程外部不可用。 只有包含该声明的过程才能使用它。 此级别的变量也称为局部变量。 可以使用 Dim 语句(带或不带 Static 关键字)声明它们。

过程和块范围密切相关。 如果在过程内声明变量,但是是在该过程内的任何块之外声明的,可以将该变量视为具有块范围,其中块是整个过程。

备注

所有局部元素(即使它们是 Static 变量)对于它们在其中出现的过程都是专用的。 不能在过程中使用 Public 关键字来声明任何元素。

模块范围

为方便起见,单个术语“模块级别”同样适用于模块、类和结构。 可以通过将声明语句放置在任何过程或块之外,但放置在模块、类或结构中来声明此级别的元素。

在模块级别进行声明时,选择的访问级别将确定范围。 包含模块、类或结构的命名空间也会影响范围。

声明为 Private 访问级别的元素可用于该模块中的每个过程,但不适用于其他模块中的任何代码。 如果不使用任何访问级别关键字,模块级别的 Dim 语句将默认为 Private。 但是,可以通过在 Dim 语句中使用 Private 关键字来使范围和访问级别更加明显。

在下面的示例中,模块中定义的所有过程都可以引用字符串变量 strMsg。 调用第二个过程时,它会在对话框中显示字符串变量 strMsg 的内容。

' Put the following declaration at module level (not in any procedure).
Private strMsg As String
' Put the following Sub procedure in the same module.
Sub initializePrivateVariable()
    strMsg = "This variable cannot be used outside this module."
End Sub
' Put the following Sub procedure in the same module.
Sub usePrivateVariable()
    MsgBox(strMsg)
End Sub

命名空间范围

如果使用 FriendPublic 关键字在模块级别声明元素,则它可用于声明元素所在的命名空间中的所有过程。 对前面的示例进行以下更改后,字符串变量 strMsg 可以在其声明的命名空间中的任何位置被代码引用。

' Include this declaration at module level (not inside any procedure).
Public strMsg As String

命名空间范围包括嵌套的命名空间。 命名空间中可用的元素也可在该命名空间内嵌套的任何命名空间内使用。

如果项目不包含任何 Namespace 语句,则项目中的所有内容都位于同一命名空间中。 在这种情况下,可以将命名空间范围视为项目范围。 模块、类或结构中的 Public 元素也可供引用其项目的任何项目使用。

选择范围

声明变量时,在选择变量的范围时,应记住以下几点。

局部变量的优点

对于任何类型的临时计算,局部变量都是一个不错的选择,原因如下:

  • 名称冲突规避。 局部变量名称不易冲突。 例如,可以创建多个包含名为 intTemp 的一个变量的不同过程。 只要每个 intTemp 声明为一个局部变量,每个过程就只能识别自己的 intTemp 版本 。 任何一个过程都可以更改其局部 intTemp 中的值,而不会影响其他过程中的 intTemp 变量。

  • 内存消耗。 局部变量仅在其过程运行时使用内存。 当过程返回到调用代码时,将释放其内存。 相比之下,共享变量和静态变量会消耗内存资源,直到应用程序停止运行为止,因此请仅在需要时使用它们。 实例变量在它们的实例继续存在时消耗内存,这使它们的效率低于局部变量,但可能比 SharedStatic 变量更高效。

最小化范围

一般情况下,声明任何变量或常量时,良好的编程做法是尽可能缩小范围(块范围是最窄范围)。 这有助于节省内存,并最大程度地减少代码错误地引用错误变量的可能性。 同样,只有在过程调用之间需要保留变量的值时,才应将变量声明为 Static

另请参阅