如何:防止过程自变量的值被更改 (Visual Basic)

如果过程将参数声明为 ByRef,Visual Basic 将为过程代码提供对调用代码中参数的基础编程元素的直接引用。 这使过程能够更改调用代码中参数的基础值。 在某些情况下,调用代码可能希望防止此类更改。

始终可以通过在过程中声明相应的参数 ByVal 来保护参数不被更改。 如果希望能够在某些情况下更改给定参数,但不更改其他参数,则可以将该参数声明为 ByRef,并让调用代码确定每次调用中的传递机制。 为此,可用括号括住相应的参数以按值传递它,或者不将其括在括号中以按引用传递它。 有关详细信息,请参阅如何:强制通过值传递参数

示例

下面的示例演示两个过程,这两个过程采用数组变量并对其元素进行操作。 increase 过程只向每个元素添加一个数组变量。 replace 过程将新数组分配给参数 a(),然后向每个元素添加一个数组。 但是,重新分配不会影响调用代码中的基础数组变量。

Public Sub increase(ByVal a() As Long)
    For j As Integer = 0 To UBound(a)
        a(j) = a(j) + 1
    Next j
End Sub
Public Sub replace(ByVal a() As Long)
    Dim k() As Long = {100, 200, 300}
    a = k
    For j As Integer = 0 To UBound(a)
        a(j) = a(j) + 1
    Next j
End Sub
Dim n() As Long = {10, 20, 30, 40}
Call increase(n)
MsgBox("After increase(n): " & CStr(n(0)) & ", " & 
    CStr(n(1)) & ", " & CStr(n(2)) & ", " & CStr(n(3)))
Call replace(n)
MsgBox("After replace(n): " & CStr(n(0)) & ", " & 
    CStr(n(1)) & ", " & CStr(n(2)) & ", " & CStr(n(3)))

第一个 MsgBox 调用显示“After increase(n): 11, 21, 31, 41”。 由于数组 n 是引用类型,因此 increase 可以更改其成员,即使传递机制为 ByVal 也是如此。

第二个 MsgBox 调用显示“After replace(n): 11, 21, 31, 41”。 由于 n 传递 ByVal,因此 replace 无法通过向调用代码中的 n 变量分配一个新数组来修改该变量。 当 replace 创建新的数组实例 k 并将其分配给局部变量 a 时,它将丢失对调用代码传入的 n 的引用。 当它更改 a 的成员时,只有本地数组 k 受到影响。 因此,replace 不会递增调用代码中数组 n 的值。

编译代码

Visual Basic 中的默认值是按值传递参数。 但是,良好的编程做法是在每个声明的参数中包含 ByValByRef 关键字。 这使得你的代码易于阅读。

另请参阅