Passaggio di argomenti per valore e per riferimento (Visual Basic)
In Visual Basic è possibile passare un argomento a una routine per valore o per riferimento. Questa operazione è nota come meccanismo di passaggio e determina se la routine può modificare l'elemento di programmazione sottostante l'argomento nel codice chiamante. La dichiarazione di routine determina il meccanismo di passaggio per ogni parametro specificando la parola chiave ByVal o ByRef.
Distinzioni
Quando si passa un argomento a una routine, tenere presente diverse distinzioni che interagiscono tra loro:
Indica se l'elemento di programmazione sottostante è modificabile o non modificabile
Indica se l'argomento stesso è modificabile o non modificabile
Indica se l'argomento viene passato per valore o per riferimento
Indica se il tipo di dati dell'argomento è un tipo valore o un tipo riferimento
Per altre informazioni, vedere Differenze tra argomenti modificabili e non modificabili e Differenze tra il passaggio di un argomento per valore e per riferimento.
Scelta del meccanismo di passaggio
È consigliabile scegliere attentamente il meccanismo di passaggio 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 di passare un argomento
ByRef
sta nel fatto che la routine può restituire un valore al codice chiamante tramite tale argomento. Il vantaggio di passare un argomentoByVal
sta nel fatto che protegge una variabile dalla modifica da parte della routine.Prestazioni. Anche se il meccanismo di passaggio può influire sulle prestazioni del codice, la differenza è in genere insignificante. Un'eccezione a quanto indicato è un tipo di valore passato
ByVal
. In questo caso, Visual Basic copia l'intero contenuto dei dati dell'argomento. Di conseguenza, per un tipo di valore di grandi dimensioni, ad esempio una struttura, può essere più efficiente usare un passaggioByRef
.Per i tipi di riferimento, viene copiato solo il puntatore ai dati (quattro byte nelle piattaforme a 32 bit, otto byte nelle piattaforme a 64 bit). Pertanto, è possibile passare argomenti di tipo
String
oObject
per valore senza danneggiare le prestazioni.
Determinazione del meccanismo di passaggio
La dichiarazione di routine specifica il meccanismo di passaggio per ogni parametro. Il codice chiamante non può eseguire l'override di un meccanismo ByVal
.
Se un parametro viene dichiarato con ByRef
, il codice chiamante può forzare l'applicazione del meccanismo ByVal
racchiudendo il nome dell'argomento tra parentesi nella chiamata. Per altre informazioni, vedere Procedura: Forzare il passaggio di un argomento per valore.
Il valore predefinito in Visual Basic prevede il passaggio degli argomenti per valore.
Quando passare un argomento per valore
Se l'elemento del codice chiamante sottostante l'argomento è un elemento non modificabile, dichiarare il parametro ByVal corrispondente. Nessun codice può modificare il valore di un elemento non modificabile.
Se l'elemento sottostante è modificabile, ma non si vuole che la routine possa modificarne il valore, dichiarare il parametro
ByVal
. Solo il codice chiamante può modificare il valore di un elemento modificabile passato per valore.
Quando passare un argomento per riferimento
Se la routine deve modificare l'elemento sottostante nel codice chiamante, dichiarare il parametro ByRef corrispondente.
Se la corretta esecuzione del codice dipende dalla modifica dell'elemento sottostante nel codice chiamante da parte della routine, dichiarare il parametro
ByRef
. Se viene passato per valore o se il codice chiamante esegue l'override del meccanismo di passaggioByRef
racchiudendo l'argomento tra parentesi, la chiamata di routine potrebbe generare risultati imprevisti.
Esempio
Descrizione
Nell'esempio seguente viene illustrato quando passare argomenti per valore e quando passarli per riferimento. La routine Calculate
ha sia un parametro ByVal
sia un parametro ByRef
. Dato un tasso di interesse, rate
, e una somma di denaro, debt
, l'attività della routine consiste nel calcolare un nuovo valore per debt
che è il risultato dell'applicazione del tasso di interesse al valore originale di debt
. Poiché debt
è un parametro ByRef
, il nuovo totale si riflette nel valore dell'argomento nel codice chiamante che corrisponde a debt
. Il parametro rate
è un parametro ByVal
perché 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
Vedi anche
- Procedure
- Parametri e argomenti delle routine
- Procedura: Passare argomenti a una routine
- Procedura: cambiare il valore di un argomento di routine
- Procedura: impedire la modifica del valore di un argomento di una routine
- Procedura: forzare il passaggio di un argomento per valore
- Passaggio di argomenti in base alla posizione e al nome
- Tipi valore e tipi di riferimento