Compartir a través de


Pasar argumentos por valor y por referencia (Visual Basic)

En Visual Basic, puede transferir un argumento a un procedimiento por valor o por referencia. Esto se conoce como mecanismo para pasar argumentos, 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 para pasar argumentos de cada parámetro mediante la palabra clave ByVal (Visual Basic) o ByRef (Visual Basic).

Distinciones

Al pasar un argumento a un procedimiento, tenga en cuenta las distintas condiciones 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 transfiere 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 (Visual Basic) y Diferencias entre pasar un argumento por valor y por referencia (Visual Basic).

Selección del mecanismo para pasar argumentos

Debe elegir minuciosamente el mecanismo para pasar argumentos de cada argumento.

  • Protección. A la hora de elegir uno de los dos mecanismos que existen para pasar argumentos, el criterio más importante que hay que tener en cuenta es la exposición al cambio de las variables de llamada. La ventaja de pasar un argumento con ByRef es que el procedimiento puede devolver un valor al código de llamada por medio del argumento. La ventaja de pasarlo con ByVal es que protege a la variable de los cambios que sobre ella pueda efectuar el procedimiento.

  • Rendimiento. Aunque el mecanismo que se utilice para pasar argumentos también puede afectar al rendimiento del código, la diferencia suele ser insignificante. Existe una excepción: cuando se pasa un tipo de valor con ByVal. En esta caso, Visual Basic copia todo el contenido de los datos del argumento. Por lo tanto, para un tipo de valor grande, como una estructura, lo más eficiente es transferirlo ByRef.

    En los tipos de referencia, sólo se copia el puntero de los datos (cuatro bytes en plataformas de 32 bits y ocho bytes en plataformas de 64 bits). Por lo tanto, se pueden pasar argumentos de tipo String u Object por valor sin que esto afecte negativamente al rendimiento.

Determinación del mecanismo para pasar argumentos

La declaración del procedimiento especifica el mecanismo para pasar argumentos de cada parámetro. El código de llamada no puede reemplazar un mecanismo ByVal .

Si un parámetro se declara con ByRef, el código de llamada puede forzar el mecanismo a ByVal agregando el argumento entre paréntesis en la llamada. Para obtener más información, vea Cómo: Forzar un argumento para que pase como un valor (Visual Basic).

En Visual Basic, los argumentos se pasan por valor de forma predeterminada.

Cuándo se debe pasar un argumento por valor

  • Si el elemento del código de llamada subyacente al argumento es un elemento no modificable, declare el parámetro correspondiente ByVal (Visual Basic). 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 modificar su valor, declare el parámetro ByVal. Sólo el código de llamada puede cambiar el valor de un elemento modificable transferido por valor.

Cuándo se debe pasar un argumento por referencia

  • Si el procedimiento necesita realmente modificar el valor subyacente en el código de llamada, declare el parámetro correspondiente ByRef (Visual Basic).

  • Si la ejecución correcta del código depende del procedimiento que cambia el elemento subyacente en el código de llamada, declare el parámetro ByRef. Si lo transfiere por valor o si el código de llamada en lugar de utilizar el mecanismo para pasar argumentos ByRef incluye el argumento entre paréntesis, la llamada al procedimiento podría producir resultados inesperados.

Ejemplo

Descripción

En el ejemplo siguiente se muestra cuándo se deben pasar argumentos por valor y cuándo se deben pasar por referencia. El procedimiento Calculate tiene un parámetro ByVal y un parámetro ByRef. Dados un tipo 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 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

Vea también

Tareas

Cómo: Pasar argumentos a un procedimiento (Visual Basic)

Cómo: Cambiar el valor de un argumento de procedimiento (Visual Basic)

Cómo: Proteger un argumento de procedimiento para que no se realicen cambios de valor (Visual Basic)

Cómo: Forzar un argumento para que pase como un valor (Visual Basic)

Conceptos

Procedimientos en Visual Basic

Argumentos y parámetros de procedimiento (Visual Basic)

Pasar argumentos por posición o por nombre (Visual Basic)

Tipos de valor y tipos de referencia