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 del procedimiento determina el mecanismo de paso de cada parámetro mediante la especificación de la palabra clave ByVal o ByRef.
Distinciones
Al pasar un argumento a un procedimiento, tenga en cuenta varias distinciones diferentes que interactúan entre sí:
Si el elemento de programación subyacente se puede modificar o no
Si el propio argumento se puede modificar o no
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 de llamada al cambio. La ventaja de pasar un argumento
ByRef
es que el procedimiento puede devolver un valor al código de llamada mediante ese argumento. La ventaja de pasar un argumentoByVal
es que protege a una variable frente al cambio realizado 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 el contenido de datos completo del argumento. Por lo tanto, en el caso de un tipo de valor grande, como una estructura, puede ser más eficaz pasarloByRef
.En 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
uObject
por valor sin afectar al rendimiento.
Determinación del mecanismo de paso
La declaración del procedimiento especifica el mecanismo de paso de cada parámetro. El código de llamada no puede invalidar un mecanismo ByVal
.
Si un parámetro se declara con ByRef
, el código de llamada puede forzar al 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.
El valor predeterminado en Visual Basic es pasar 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 quiere 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 genuina 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 de que el procedimiento cambie el elemento subyacente en el código de llamada, declare el parámetro
ByRef
. Si lo pasa por valor o si el código de llamada invalida el mecanismo de pasoByRef
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 hacerlo por referencia. El procedimiento Calculate
tiene un parámetro ByVal
y 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 la tasa 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 parámetro ByVal
, 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
- Procedimientos
- Argumentos y parámetros de procedimiento
- Procedimiento para pasar argumentos a un procedimiento
- Procedimiento para cambiar el valor de un argumento de procedimiento
- Procedimiento para proteger un argumento de procedimiento para que no se realicen cambios de valor
- Procedimiento para forzar un argumento para que pase como un valor
- Paso de argumentos por posición o por nombre
- Value Types and Reference Types