通过值和通过引用传递参数 (Visual Basic)

在 Visual Basic 中,可通过值或通过引用将参数传递给过程。 这称为“传入机制”,它确定过程是否可修改调用代码中的参数所基于的编程元素。 过程声明通过指定 ByValByRef 关键字来确定每个参数的传入机制。

区别

将参数传递给过程时,请注意彼此交互的几个不同的区别:

  • 基础编程元素是否可修改

  • 参数本身是否可修改

  • 参数是通过值还是通过引用传递的

  • 参数数据类型是值类型还是引用类型

有关详细信息,请参阅可修改参数和不可修改参数之间的区别以及通过值和通过引用传递参数之间的区别

选择传入机制

应为每个参数仔细选择传入机制。

  • 保护。 在两个传入机制之间进行选择时,最重要的标准是公开调用变量来进行更改。 传递参数 ByRef 的优点是,过程可通过该参数将值返回给调用代码。 传递参数 ByVal 的优点是,它可防止过程更改变量。

  • 性能。 尽管传入机制可能会影响代码的性能,但差别通常并不显著。 这种情况的一个例外是,传递了 ByVal 的一个值类型。 在这种情况下,Visual Basic 会复制参数的整个数据内容。 因此,对于大型值类型(如结构),向它传递 ByRef 会更有效。

    对于引用类型,仅复制指向数据的指针(在 32 位平台上是 4 个字节,在 64 位平台上是 8 个字节)。 因此,可通过值传递 StringObject 类型的参数,而不损害性能。

确定传入机制

过程声明指定每个参数的传入机制。 调用代码无法替代 ByVal 机制。

如果使用 ByRef 声明参数,则调用代码可通过在调用中将参数名称括在括号中来强制机制采用 ByVal。 有关详细信息,请参阅如何:强制通过值传递参数

Visual Basic 中的默认设置是通过值传递参数。

何时通过值传递参数

  • 如果参数所基于的调用代码元素不可修改,则声明相应的参数 。 没有代码可更改不可修改的元素的值。

  • 如果基础元素是可修改的,但你不希望该过程能够更改其值,则声明参数 ByVal。 只有调用代码可更改通过值传递的可修改元素的值。

何时通过引用传递参数

  • 如果过程确实需要更改调用代码中的基础元素,请声明相应的参数 ByRef

  • 如果代码的正确执行取决于过程更改调用代码中的基础元素,请声明参数 ByRef。 如果通过值传递它,或者调用代码通过将参数括在括号中来替代 ByRef 传入机制,则过程调用可能会产生意外的结果。

示例

说明

下面的示例演示了何时通过值传递参数,何时又通过引用传递参数。 过程 Calculate 具有 ByValByRef 参数。 如果利率为 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

请参阅