在 Visual Basic 中,可以 按值 或 按引用将参数传递给过程。 这称为 传递机制,它确定该过程是否可以修改调用代码中自变量的基础编程元素。 过程声明通过指定 ByVal 或 ByRef 关键字来确定每个参数的传递机制。
区别
将参数传递给过程时,请注意相互交互的几种不同区别:
基础编程元素是可修改的还是不可修改的
参数本身是可修改的还是不可修改的
参数是按值传递还是按引用传递
参数数据类型是值类型还是引用类型
有关详细信息,请参阅 “可修改参数”和“不可修改参数”之间的差异 以及 “按值传递参数”和“按引用”之间的差异。
选择传入机制
应为每个参数仔细选择传入机制。
保护。 在选择两种传递机制时,最重要的标准是调用变量暴露于变化的程度。 传递参数
ByRef
的优点是该过程可以通过该参数将值返回到调用代码。 传递参数ByVal
的优点是它防止变量被过程更改。性能。 尽管传递机制可能会影响代码的性能,但差异通常无关紧要。 这种情况的一个例外是,传递了
ByVal
的一个值类型。 在这种情况下,Visual Basic 将复制参数的整个数据内容。 因此,对于大型值类型(如结构),传递它ByRef
可能更高效。对于引用类型,仅复制指向数据的指针(32 位平台上有 4 个字节,64 位平台上有 8 个字节)。 因此,您可以按值传递类型
String
或Object
的参数,而不会影响性能。
确定传入机制
过程声明指定每个参数的传递机制。 调用代码无法替代 ByVal
机制。
如果参数是用 ByRef
声明的,调用代码可以通过在调用时将参数名称用括号括起来来强制机制为 ByVal
。 有关详细信息,请参阅 “如何:强制参数由值传递”。
Visual Basic 中的默认值是按值传递参数。
何时按值传递参数
如果参数基础的调用代码元素是不可修改的元素,请声明相应的参数 ByVal。 任何代码都无法更改不可修改元素的值。
如果基础元素可修改,但不希望该过程能够更改其值,请声明参数
ByVal
。 只有调用代码能改变按值传递的可修改元素的值。
何时通过引用传递参数
如果过程确实需要更改调用代码中的基础元素,请声明相应的参数 ByRef。
如果代码的正确执行取决于更改调用代码中基础元素的过程,请声明参数
ByRef
。 如果按值传递它,或者调用代码通过将参数括在括号中来替代ByRef
传递机制,则过程调用可能会产生意外的结果。
示例:
DESCRIPTION
下面的示例演示了何时按值传递参数,以及何时按引用传递参数。 过程 Calculate
具有一个 ByVal
参数和一个 ByRef
参数。 如果利率为 rate
且金额总数为 debt
,则此过程的任务是为 debt
计算一个新值,这通过将利率应用于 debt
的原始值得出。 由于 debt
是一个 ByRef
参数,因此新总计反映在调用代码中与该参数对应的 debt
参数的值中。 参数 rate
是一个 ByVal
参数,因为 Calculate
不应更改其值。
代码
Module Module1
Sub Main()
' Two interest rates are declared, one a constant and one a
' variable.
Const highRate As Double = 12.5
Dim lowRate = highRate * 0.6
Dim initialDebt = 4999.99
' Make a copy of the original value of the debt.
Dim debtWithInterest = initialDebt
' Calculate the total debt with the high interest rate applied.
' Argument highRate is a constant, which is appropriate for a
' ByVal parameter. Argument debtWithInterest must be a variable
' because the procedure will change its value to the calculated
' total with interest applied.
Calculate(highRate, debtWithInterest)
' Format the result to represent currency, and display it.
Dim debtString = Format(debtWithInterest, "C")
Console.WriteLine("What I owe with high interest: " & debtString)
' Repeat the process with lowRate. Argument lowRate is not a
' constant, but the ByVal parameter protects it from accidental
' or intentional change by the procedure.
' Set debtWithInterest back to the original value.
debtWithInterest = initialDebt
Calculate(lowRate, debtWithInterest)
debtString = Format(debtWithInterest, "C")
Console.WriteLine("What I owe with low interest: " & debtString)
End Sub
' Parameter rate is a ByVal parameter because the procedure should
' not change the value of the corresponding argument in the
' calling code.
' The calculated value of the debt parameter, however, should be
' reflected in the value of the corresponding argument in the
' calling code. Therefore, it must be declared ByRef.
Sub Calculate(ByVal rate As Double, ByRef debt As Double)
debt = debt + (debt * rate / 100)
End Sub
End Module