Passaggio di argomenti per valore e per riferimento (Visual Basic)

In Visual Basic è possibile passare un argomento a una routine in base al valore o in base al riferimento. Tale funzionalità è nota come meccanismo di passaggio e determina se la routine può modificare l'elemento di programmazione sottostante all'argomento nel codice chiamante. Il meccanismo di passaggio è definito nella dichiarazione della routine di ogni parametro mediante la specifica della parola chiave ByVal (Visual Basic) o ByRef (Visual Basic).

Differenze

È importante tenere presenti i diversi fattori distintivi che interagiscono nel corso del passaggio di un argomento a una routine.

  • La possibilità che l'elemento di programma sottostante sia modificabile o meno

  • La possibilità che l'argomento stesso sia modificabile o meno

  • La possibilità che l'argomento venga passato in base al valore o al riferimento

  • La possibilità che il tipo di dati dell'argomento sia un tipo di valore o di riferimento

Per ulteriori informazioni, vedere Differenze tra argomenti modificabili e non modificabili (Visual Basic) e Differenze tra il passaggio di un argomento per valore e per riferimento (Visual Basic).

Scelta del meccanismo di passaggio

La scelta del meccanismo di passaggio deve essere valutata attentamente per ogni argomento.

  • Protezione. Nella scelta tra i due meccanismi di passaggio, il criterio più importante è l'esposizione delle variabili chiamanti da modificare. Il vantaggio del passaggio di un argomento tramite ByRef è che la routine può restituire un valore al codice di chiamata tramite l'argomento. Il vantaggio del passaggio di un argomento tramite valore ByVal è che esso impedisce che la variabile venga modificata dalla routine.

  • Prestazioni. Sebbene il meccanismo di passaggio possa avere effetto sulle prestazioni del codice, la differenza è in genere irrilevante. Un'eccezione è rappresentata da un tipo di valore passato tramite valore (ByVal). In questo caso, Visual Basic consente di copiare l'intero contenuto di dati dell'argomento. Di conseguenza, per un tipo di valore di grandi dimensioni, come una struttura, il passaggio in base al riferimento (ByRef) risulta più efficiente.

    Per i tipi di riferimento, viene copiato solo il puntatore ai dati (quattro byte sulle piattaforme a 32 bit, otto byte su quelle a 64 bit). Pertanto, è possibile passare argomenti di tipo String o Object in base al valore senza compromettere le prestazioni.

Determinazione del meccanismo di passaggio

Nella dichiarazione della routine è specificato il meccanismo di passaggio di ogni parametro. Il codice chiamante non può eseguire l'override di un meccanismo ByVal ma, se un parametro viene dichiarato utilizzando ByRef, il codice chiamante può forzare l'uso del meccanismo ByVal racchiudendo tra parentesi il nome dell'argomento nella chiamata.

Per impostazione predefinita, in Visual Basic gli argomenti vengono passati per valore. Per semplificare la lettura del codice, è possibile utilizzare la parola chiave ByVal. È buona norma di programmazione includere la parola chiave ByVal o ByRef in ogni parametro dichiarato.

Quando passare un argomento per valore

  • Se l'elemento di codice chiamante sottostante all'argomento non è modificabile, dichiarare il parametro corrispondente ByVal (Visual Basic). Nessun codice può modificare il valore di un elemento non modificabile.

  • Se l'elemento sottostante è modificabile, ma non si desidera consentire alla routine di modificarne il valore, dichiarare il parametro ByVal. Solo il codice chiamante può modificare il valore di un elemento modificabile passato in base al valore.

Quando passare un argomento per riferimento

  • Se la routine richiede la modifica dell'elemento sottostante nel codice chiamante, dichiarare il parametro corrispondente ByRef (Visual Basic).

  • Se l'esecuzione corretta del codice dipende dalla modifica dell'elemento nel codice chiamante da parte della routine, dichiarare il parametro ByRef. Se il passaggio avviene in base al valore o il codice chiamante esegue l'override del meccanismo di passaggio ByRef racchiudendo l'argomento tra parentesi, la chiamata alla routine potrebbe produrre risultati imprevisti.

Esempio

Descrizione

Nell'esempio seguente viene illustrato quando passare argomenti per valore e quando passarli per riferimento. La routine Calculate dispone sia di un parametro ByVal che di un parametro ByRef. Dati un tasso di interesse, rate, e una somma di denaro, debt, l'attività della routine consiste nel calcolare un nuovo valore per debt che sia il risultato dell'applicazione del tasso di interesse al valore originale di debt. Poiché debt è un parametro ByRef, il nuovo totale viene riflesso nel valore dell'argomento nel codice chiamante che corrisponde a debt. Il parametro rate è un parametro ByVal poiché Calculate non deve modificarne il valore.

Codice

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

Vedere anche

Attività

Procedura: passare argomenti a una routine (Visual Basic)

Procedura: cambiare il valore di un argomento di routine (Visual Basic)

Procedura: impedire la modifica del valore di un argomento di una routine (Visual Basic)

Procedura: forzare il passaggio di un argomento per valore (Visual Basic)

Concetti

Routine in Visual Basic

Parametri e argomenti delle routine (Visual Basic)

Passaggio di argomenti in base alla posizione e al nome (Visual Basic)

Altre risorse

Implementazione del tipo di dati (Visual Basic)