Compartir a través de


Pasar argumentos por valor y por referencia (Visual Basic)

En Visual Basic, puede pasar un argumento a un procedimiento por valor o por referencia. Esto se conoce como mecanismo de paso y determina si el procedimiento puede modificar el elemento de programación subyacente al argumento en el código de llamada. La declaración de procedimiento determina el mecanismo de paso para cada parámetro especificando la palabra clave ByVal o ByRef .

Distinciones

Al pasar un argumento a un procedimiento, tenga en cuenta varias diferencias diferentes que interactúan entre sí:

  • Si el elemento de programación subyacente es modificable o no modificable

  • Si el propio argumento es modificable o no modificable

  • Si el argumento se pasa por valor o por referencia

  • Si el tipo de datos del argumento es un tipo de valor o un tipo de referencia

Para obtener más información, vea Diferencias entre argumentos modificables y no modificables y diferencias entre pasar un argumento por valor y por referencia.

Elección del mecanismo de paso

Debe elegir el mecanismo de paso de cada argumento cuidadosamente.

  • Protección. Al elegir entre los dos mecanismos de paso, el criterio más importante es la exposición de las variables a cambios. La ventaja de pasar un argumento ByRef es que el procedimiento puede devolver un valor al código que realiza la llamada a través de ese argumento. La ventaja de pasar un argumento ByVal es que protege una variable de ser modificada por el procedimiento.

  • Rendimiento. Aunque el mecanismo de paso puede afectar al rendimiento del código, la diferencia suele ser insignificante. Una excepción a esto es un tipo de valor pasado ByVal. En este caso, Visual Basic copia todo el contenido de los datos del argumento. Por lo tanto, en el caso de un tipo de valor grande, como una estructura, puede ser más eficaz pasarlo ByRef.

    Para los tipos de referencia, solo se copia el puntero a los datos (cuatro bytes en plataformas de 32 bits, ocho bytes en plataformas de 64 bits). Por lo tanto, puede pasar argumentos de tipo String o Object por valor sin dañar el rendimiento.

Determinación del mecanismo de paso

La declaración de procedimiento especifica el mecanismo de paso para cada parámetro. El código de llamada no puede invalidar un ByVal mecanismo.

Si se declara un parámetro con ByRef, el código de llamada puede forzar el mecanismo a ByVal mediante la inclusión del nombre del argumento entre paréntesis en la llamada. Para obtener más información, vea Procedimiento para forzar un elemento para que pase como un valor.

La configuración predeterminada en Visual Basic es pasar los argumentos por valor.

Cuándo pasar un argumento por valor

  • Si el elemento de código de llamada subyacente al argumento es un elemento no modificable, declare el parámetro correspondiente ByVal. Ningún código puede cambiar el valor de un elemento no modificable.

  • Si el elemento subyacente es modificable, pero no desea que el procedimiento pueda cambiar su valor, declare el parámetro ByVal. Solo el código de llamada puede cambiar el valor de un elemento modificable pasado por valor.

Cuándo pasar un argumento por referencia

  • Si el procedimiento tiene una necesidad original de cambiar el elemento subyacente en el código de llamada, declare el parámetro ByRef correspondiente.

  • Si la ejecución correcta del código depende del procedimiento que cambia el elemento subyacente en el código que llama, declare el parámetro ByRef. Si se pasa por valor o si el código de llamada anula el ByRef mecanismo de paso mediante la inclusión del argumento entre paréntesis, la llamada al procedimiento podría generar resultados inesperados.

Ejemplo

Descripción

En el ejemplo siguiente se muestra cuándo pasar argumentos por valor y cuándo pasarlos por referencia. El procedimiento Calculate tiene tanto un parámetro ByVal como un parámetro ByRef. Dada una tasa de interés, rate, y una suma de dinero, debt, la tarea del procedimiento es calcular un nuevo valor para debt que sea el resultado de aplicar el tipo de interés al valor original de debt. Dado que debt es un parámetro ByRef, el nuevo total se refleja en el valor del argumento en el código de llamada que corresponde a debt. El parámetro rate es un ByVal parámetro porque Calculate no debe cambiar su valor.

Código

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

Consulte también