Visual Basic 中的范围Scope in Visual Basic

已声明元素的作用域是所有可引用它的代码的集合,无需限定其名称或通过Imports 语句(.net 命名空间和类型)提供它。The scope of a declared element is the set of all code that can refer to it without qualifying its name or making it available through an Imports Statement (.NET Namespace and Type). 元素可以具有以下级别之一的作用域:An element can have scope at one of the following levels:

层次Level 说明Description
块范围Block scope 仅在声明它的代码块内可用Available only within the code block in which it is declared
过程范围Procedure scope 对声明它的过程中的所有代码可用Available to all code within the procedure in which it is declared
模块范围Module scope 适用于声明它的模块、类或结构中的所有代码Available to all code within the module, class, or structure in which it is declared
命名空间范围Namespace scope 可用于声明它的命名空间中的所有代码Available to all code in the namespace in which it is declared

这种级别的作用域从最小(块)到最宽(命名空间)的范围进度,其中最窄的范围指的是可以引用元素而不进行限定的最小代码集。These levels of scope progress from the narrowest (block) to the widest (namespace), where narrowest scope means the smallest set of code that can refer to the element without qualification. 有关详细信息,请参阅本页上的 "范围级别"。For more information, see "Levels of Scope" on this page.

指定作用域和定义变量Specifying Scope and Defining Variables

在声明元素时指定其作用域。You specify the scope of an element when you declare it. 范围可能取决于以下因素:The scope can depend on the following factors:

  • 声明元素的区域(块、过程、模块、类或结构)The region (block, procedure, module, class, or structure) in which you declare the element

  • 包含元素声明的命名空间The namespace containing the element's declaration

  • 为元素声明的访问级别The access level you declare for the element

定义名称相同但范围不同的变量时请小心,因为这样做可能会导致意外的结果。Use care when you define variables with the same name but different scope, because doing so can lead to unexpected results. 有关详细信息,请参阅 References to Declared ElementsFor more information, see References to Declared Elements.

范围级别Levels of Scope

编程元素可在声明它的整个区域内使用。A programming element is available throughout the region in which you declare it. 同一区域中的所有代码都可以引用元素,而无需限定其名称。All code in the same region can refer to the element without qualifying its name.

块范围Block Scope

块是包含在启动和终止声明语句中的一组语句,如下所示:A block is a set of statements enclosed within initiating and terminating declaration statements, such as the following:

  • DoLoopDo and Loop

  • For [Each] 和 NextFor [Each] and Next

  • IfEnd IfIf and End If

  • SelectEnd SelectSelect and End Select

  • SyncLockEnd SyncLockSyncLock and End SyncLock

  • TryEnd TryTry and End Try

  • WhileEnd WhileWhile and End While

  • WithEnd WithWith and End With

如果在块中声明一个变量,则只能在该块内使用它。If you declare a variable within a block, you can use it only within that block. 在下面的示例中,整数变量的作用域 cubeIfEnd If之间的块,当执行传递到块时,就不能再引用 cubeIn the following example, the scope of the integer variable cube is the block between If and End If, and you can no longer refer to cube when execution passes out of the block.

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

备注

即使变量的作用域限制为块,其生存期仍是整个过程的生存期。Even if the scope of a variable is limited to a block, its lifetime is still that of the entire procedure. 如果在过程中多次输入块,则每个块变量将保留其以前的值。If you enter the block more than once during the procedure, each block variable retains its previous value. 若要避免在这种情况下出现意外结果,最好在块的开头初始化块变量。To avoid unexpected results in such a case, it is wise to initialize block variables at the beginning of the block.

过程范围Procedure Scope

在过程中声明的元素在该过程之外不可用。An element declared within a procedure is not available outside that procedure. 只有包含声明的过程可以使用它。Only the procedure that contains the declaration can use it. 此级别的变量也称为局部变量Variables at this level are also known as local variables. Dim 语句声明它们,无论是还是不带Static关键字。You declare them with the Dim Statement, with or without the Static keyword.

过程和块范围密切相关。Procedure and block scope are closely related. 如果在过程内但在该过程中的任何块外声明变量,则可以将变量视为具有块范围,其中块是整个过程。If you declare a variable inside a procedure but outside any block within that procedure, you can think of the variable as having block scope, where the block is the entire procedure.

备注

所有本地元素(即使它们是 Static 变量)都专用于它们出现的过程。All local elements, even if they are Static variables, are private to the procedure in which they appear. 不能在过程中使用Public关键字声明任何元素。You cannot declare any element using the Public keyword within a procedure.

模块范围Module Scope

为方便起见,单术语模块级别同样适用于模块、类和结构。For convenience, the single term module level applies equally to modules, classes, and structures. 您可以通过将声明语句置于任何过程或块的外部,但在模块、类或结构中,在此级别声明元素。You can declare elements at this level by placing the declaration statement outside of any procedure or block but within the module, class, or structure.

在模块级别进行声明时,所选的访问级别将确定范围。When you make a declaration at the module level, the access level you choose determines the scope. 包含模块、类或结构的命名空间还会影响范围。The namespace that contains the module, class, or structure also affects the scope.

声明专用访问级别的元素可用于该模块中的每个过程,但不能用于不同模块中的任何代码。Elements for which you declare Private access level are available to every procedure in that module, but not to any code in a different module. 如果不使用任何访问级别关键字,模块级别的 Dim 语句默认为 PrivateThe Dim statement at module level defaults to Private if you do not use any access level keywords. 但是,可以通过在 Dim 语句中使用 Private 关键字,使作用域和访问级别更为明显。However, you can make the scope and access level more obvious by using the Private keyword in the Dim statement.

在下面的示例中,模块中定义的所有过程都可以引用字符串变量 strMsgIn the following example, all procedures defined in the module can refer to the string variable strMsg. 调用第二个过程时,会在对话框中 strMsg 显示字符串变量的内容。When the second procedure is called, it displays the contents of the string variable strMsg in a dialog box.

' 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

命名空间范围Namespace Scope

如果使用FriendPublic关键字在模块级别声明一个元素,则该元素将可用于声明该元素的整个命名空间中的所有过程。If you declare an element at module level using the Friend or Public keyword, it becomes available to all procedures throughout the namespace in which the element is declared. 对于前面的示例的以下更改,字符串变量 strMsg 可以在其声明的命名空间中的任何位置通过代码引用。With the following alteration to the preceding example, the string variable strMsg can be referred to by code anywhere in the namespace of its declaration.

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

命名空间范围包括嵌套命名空间。Namespace scope includes nested namespaces. 命名空间中的可用元素也可以从嵌套在该命名空间中的任何命名空间中使用。An element available from within a namespace is also available from within any namespace nested inside that namespace.

如果你的项目不包含任何命名空间语句,则项目中的所有内容都在相同的命名空间中。If your project does not contain any Namespace Statements, everything in the project is in the same namespace. 在这种情况下,可以将命名空间范围视为项目范围。In this case, namespace scope can be thought of as project scope. 模块、类或结构中的 Public 元素也可用于引用其项目的任何项目。Public elements in a module, class, or structure are also available to any project that references their project.

范围选择Choice of Scope

当你声明变量时,在选择其作用域时应牢记以下几点。When you declare a variable, you should keep in mind the following points when choosing its scope.

局部变量的优点Advantages of Local Variables

局部变量对于任何类型的临时计算都是一个不错的选择,原因如下:Local variables are a good choice for any kind of temporary calculation, for the following reasons:

  • 避免名称冲突。Name Conflict Avoidance. 局部变量名称不容易发生冲突。Local variable names are not susceptible to conflict. 例如,可以创建几个不同的过程,其中包含一个名为 intTemp的变量。For example, you can create several different procedures containing a variable called intTemp. 只要每个 intTemp 都声明为局部变量,每个过程就只能识别自己的 intTemp版本。As long as each intTemp is declared as a local variable, each procedure recognizes only its own version of intTemp. 任何一个过程都可以更改其本地 intTemp 中的值,而不会影响其他过程中的 intTemp 变量。Any one procedure can alter the value in its local intTemp without affecting intTemp variables in other procedures.

  • 内存消耗。Memory Consumption. 局部变量仅在其过程正在运行时占用内存。Local variables consume memory only while their procedure is running. 当过程返回到调用代码时,将释放其内存。Their memory is released when the procedure returns to the calling code. 相反,共享静态变量将消耗内存资源,直到应用程序停止运行,因此仅在必要时才使用它们。By contrast, Shared and Static variables consume memory resources until your application stops running, so use them only when necessary. 实例变量会在其实例继续存在时使用内存,这使得它们的效率低于局部变量,但可能比 SharedStatic 变量更有效。Instance variables consume memory while their instance continues to exist, which makes them less efficient than local variables, but potentially more efficient than Shared or Static variables.

最小化范围Minimizing Scope

通常情况下,在声明任何变量或常量时,最好将范围设置为尽可能缩小(块范围是最小)。In general, when declaring any variable or constant, it is good programming practice to make the scope as narrow as possible (block scope is the narrowest). 这有助于节省内存,并最大程度地减少代码错误引用错误变量的几率。This helps conserve memory and minimizes the chances of your code erroneously referring to the wrong variable. 同样,仅当需要在过程调用之间保留变量值时,才应将该变量声明为静态Similarly, you should declare a variable to be Static only when it is necessary to preserve its value between procedure calls.

另请参阅See also