如何:更改过程参数的值

更新:2007 年 11 月

在调用过程时,您提供的各个实参分别对应于过程中定义的一个形参。在某些情况下,过程代码可以更改调用代码中作为实参基础的值。在其他情况下,过程只可以更改实参的本地副本。

在调用过程时,Visual Basic 创建了每个以 ByVal 机制传递的实参的本地副本。对于传递机制为 ByRef 的每个实参,Visual Basic 为过程代码提供对调用代码中作为实参基础的编程元素的一个直接引用。

如果调用代码中的基础元素是一个可修改的元素,并且实参传递机制为 ByRef,则过程代码可以使用直接引用来更改调用代码中元素的值。

更改基础值

更改调用代码中过程实参的基础值

  1. 在过程声明中,为与实参对应的形参指定 ByRef

  2. 在调用代码中,将可修改编程元素作为实参传递。

  3. 在调用代码中,不要将实参列表中的实参放在括号内。

  4. 在过程代码中,使用形参名称将值赋给调用代码中的基础元素。

请参见下面的示例中的演示。

更改本地副本

如果调用代码中的基础元素是不可更改元素,或实参的传递方式为 ByVal,则过程不能在调用代码中更改它的值。但是,过程可以更改这样一个实参的本地副本。

更改过程代码中过程实参的副本

  1. 在过程声明中,为与实参对应的形参指定 ByVal

    - 或 -

    在调用代码中,将实参列表中的实参放在括号内。这就强制 Visual Basic 通过值传递实参,即使对应的形参指定了 ByRef。

  2. 在过程代码中,使用形参名称将值赋给实参的本地副本。调用代码中的基础值不变。

示例

下面的示例演示获取数组变量并对其元素进行操作的两个过程。increase 过程只是让每个元素加 1。replace 过程将新数组赋给形参 a(),再让每个元素加 1。

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 中的默认行为是通过值传递实参。不过,在声明每个形参时都使用关键字 ByValByRef 是一种很好的编程习惯。这将增强代码的可读性。

安全性

允许过程更改调用代码中实参所代表的值始终存在潜在的风险。请确保您希望更改这个值,并在使用该值前首先检查其有效性。

请参见

任务

如何:将参数传递给过程

如何:防止过程参数的值被更改

如何:强制通过值传递参数

概念

Visual Basic 中的过程

过程参数和变量

通过值和通过引用传递参数

可更改和不可更改参数之间的差异

通过值传递参数和通过引用传递参数之间的差异

通过位置和通过名称的参数传递

值类型和引用类型