如何:防止过程自变量的值被更改 (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 中的默认值是按值传递参数。 但是,良好的编程做法是在每个声明的参数中包含 ByVal 或 ByRef 关键字。 这使得你的代码易于阅读。