已声明元素的范围是一组所有代码,这些代码可以在不限定其名称的情况下引用它,或者通过 Imports 语句(.NET 命名空间和类型)提供它。 元素可以具有以下级别之一的范围:
级别 | DESCRIPTION |
---|---|
块范围 | 仅在声明的代码块内可用 |
过程范围 | 可用于在其中声明它的过程内的所有代码 |
模块范围 | 在声明的模块、类或结构内,可供所有代码使用 |
命名空间范围 | 在声明的命名空间内,适用于所有代码。 |
这些范围级别从最窄(块)发展到最宽(命名空间),其中 最窄的范围 意味着可以引用元素的最小代码集,而无需限定。 有关详细信息,请参阅此页上的“范围级别”。
指定作用域和定义变量
声明元素时指定元素的范围。 范围可能取决于以下因素:
在其中声明元素的区域(块、过程、模块、类或结构)
包含元素声明的命名空间
为元素声明的访问级别
定义名称相同但范围不同的变量时,请小心,因为这样做可能会导致意外的结果。 有关详细信息,请参阅 对声明元素的引用。
范围级别
编程元素在声明它的整个区域都可用。 同一区域中的所有代码都可以引用该元素,而无需限定其名称。
块范围
块是一组包含在启动和终止声明语句中的语句,如下所示:
Do
和Loop
For
[Each
] 和Next
If
和End If
Select
和End Select
SyncLock
和End SyncLock
Try
和End Try
While
和End While
With
和End With
如果在块中声明变量,则只能在该块内使用它。 在下面的示例中,整数变量cube
的作用域是If
到End If
之间的代码块,当执行超出这个块时,不能再引用cube
。
If n < 1291 Then
Dim cube As Integer
cube = n ^ 3
End If
注释
即使一个变量的范围仅限于块,其生存期仍为整个过程的生存期。 如果在过程中多次输入块,则每个块变量都会保留其以前的值。 为了避免此类情况下出现意外结果,最好在块开头初始化块变量。
过程范围
在该过程中声明的元素在该过程之外不可用。 只有包含该声明的过程才能使用它。 此级别的变量也称为 局部变量。 使用 Dim 语句声明它们,其中包含或不使用 Static 关键字。
过程和块范围密切相关。 如果在过程内声明变量,但在该过程中的任何块外部,则可以将该变量视为具有块范围,其中块是整个过程。
注释
所有局部元素(即使它们是 Static
变量)都是它们所显示的过程的私有元素。 不能在过程中使用 Public 关键字声明任何元素。
模块范围
为方便起见,单个术语 模块级别 同样适用于模块、类和结构。 可以通过将声明语句置于任何过程或块之外,但在模块、类或结构中,在此级别声明元素。
在模块级别进行声明时,选择的访问级别将确定范围。 包含模块、类或结构的命名空间也会影响范围。
声明 专用 访问级别的元素可用于该模块中的每个过程,但不适用于不同模块中的任何代码。 如果不使用任何访问级别关键字,模块级别的Dim
语句将默认为Private
。 但是,您可以在Private
语句中使用Dim
关键字,使范围和访问级别更加明显。
在以下示例中,模块中定义的所有过程都可以引用字符串变量 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
命名空间范围
如果使用 Friend 或 Public 关键字在模块级别声明元素,则它可用于声明元素的命名空间中的所有过程。 对前面的示例进行以下更改后,字符串变量 strMsg
可以通过代码在其声明的命名空间中的任何位置引用。
' Include this declaration at module level (not inside any procedure).
Public strMsg As String
命名空间范围包括嵌套命名空间。 命名空间中可用的元素也可在该命名空间内嵌套的任何命名空间内使用。
如果项目不包含任何 Namespace 语句,则项目中的所有内容都位于同一命名空间中。 在这种情况下,命名空间范围可以视为项目范围。
Public
模块、类或结构中的元素也可供任何引用其项目的其他项目使用。
选择范围
声明变量时,在选择变量范围时,应记住以下几点。
局部变量的优点
对于任何类型的临时计算,局部变量是一个不错的选择,原因如下:
名称冲突规避。 局部变量名称不容易发生冲突。 例如,可以创建几个包含名为
intTemp
变量的不同过程。 只要每个intTemp
变量声明为局部变量,每个过程就只识别其自己的版本intTemp
。 任何一个过程都可以更改其局部intTemp
值,而不会影响intTemp
其他过程中的变量。内存消耗。 局部变量仅在运行其过程时消耗内存。 当过程返回到调用代码时,其内存将释放。 相比之下, 共享 变量和 静态 变量会消耗内存资源,直到应用程序停止运行,因此仅在必要时使用它们。 实例变量 在实例继续存在时消耗内存,这使得它们比局部变量效率低,但可能比
Shared
变量Static
更高效。
最小化范围
一般情况下,声明任何变量或常量时,使范围尽可能窄(块范围最窄)是很好的编程做法。 这有助于节省内存,并最大程度地减少错误引用错误变量的代码几率。 同样,仅当有必要在过程调用之间保留变量的值时,才应将变量声明为 Static 。