调用过程时,提供的每个参数对应于过程中定义的一个参数。 在某些情况下,过程代码可以更改调用代码中参数的基础值。 在其他情况下,过程只能更改参数的本地副本。
调用该过程时,Visual Basic 会生成 ByVal 传递的每个参数的本地副本。 对于传递 ByRef 的每个参数,Visual Basic 为过程代码提供对调用代码中自变量的基础编程元素的直接引用。
如果调用代码中的基础元素是可修改的元素,并且传递 ByRef
参数,则过程代码可以使用直接引用来更改调用代码中的元素值。
更改基础值
更改调用代码中过程参数的基础值
在过程声明中,为与参数对应的参数指定 ByRef 。
在调用代码中,将可修改的编程元素作为参数传递。
在调用代码中,不要将参数括在参数列表中的括号中。
在过程代码中,使用参数名称将值分配给调用代码中的基础元素。
有关演示,请参阅下一个示例。
更改本地副本
如果调用代码中的基础元素是不可修改的元素,或者传递 ByVal
参数,则该过程无法在调用代码中更改其值。 但是,该过程可以更改此类参数的本地副本。
更改过程代码中过程参数的副本
在过程声明中,为与参数对应的参数指定 ByVal 。
-或-
在调用代码中,将参数括在参数列表中的括号中。 这强制 Visual Basic 按值传递参数,即使相应的参数指定
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(ByRef 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
是引用类型,因此即使传递机制为replace
,也可以更改其ByVal
的成员。
第二个 MsgBox
调用显示“After replace(n): 101, 201, 301”。 由于n
被传递给ByRef
,replace
因此可以在调用代码中修改变量n
,并为其分配一个新数组。 由于 n
是引用类型, replace
因此还可以更改其成员。
可以防止过程在调用代码中修改变量本身。 请参阅 如何:保护过程参数免受值更改。
编译代码
通过引用传递变量时,必须使用 ByRef
关键字来指定此机制。
Visual Basic 中的默认值是按值传递参数。 但是,最好是将 ByVal 或 ByRef 关键字包含在每个声明的参数中。 这使代码更易于阅读。
.NET Framework 安全性
在允许过程更改调用代码中自变量的值时,始终存在潜在风险。 请确保预期此值会更改,并准备好在使用它之前检查该值的有效性。