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. Questo è noto come meccanismo di passaggio e determina se la procedura può modificare l'elemento di programmazione sottostante all'argomento nel codice chiamante. La dichiarazione di procedura determina il meccanismo di passaggio per ogni parametro specificando la parola chiave ByVal o ByRef .

Distinzioni

Quando si passa un argomento a una procedura, tenere presente diverse distinzione che interagiscono tra loro:

  • Indica se l'elemento di programmazione sottostante è modificabile o non modificabile

  • 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 di valore o un tipo di riferimento

Per altre informazioni, vedere Differenze tra argomenti modificabili e non modificabili edifferenze tra il passaggio di un argomento per valore e per riferimento.

Scelta del meccanismo di passaggio

È consigliabile scegliere il meccanismo di passaggio con attenzione per ogni argomento.

  • Protezione. Nella scelta tra i due meccanismi di passaggio, il criterio più importante è l'esposizione delle variabili chiamanti alla modifica. Il vantaggio di passare un argomento ByRef è che la procedura può restituire un valore al codice chiamante tramite tale argomento. Il vantaggio di passare un argomento ByVal è che protegge una variabile da modificare dalla procedura.

  • Prestazioni. Anche se il meccanismo di passaggio può influire sulle prestazioni del codice, la differenza è in genere insignificante. Un'eccezione a questa è un tipo di valore passato ByVal. In questo caso, Visual Basic copia l'intero contenuto dei dati dell'argomento. Pertanto, per un tipo di valore di grandi dimensioni, ad esempio una struttura, può essere più efficiente passare ByRef.

    Per i tipi di riferimento, viene copiato solo il puntatore ai dati (quattro byte su piattaforme a 32 bit, otto byte su piattaforme a 64 bit). È pertanto possibile passare argomenti di tipo String o Object per valore senza danneggiare le prestazioni.

Determinazione del meccanismo di passaggio

La dichiarazione di procedura specifica il meccanismo di passaggio per ogni parametro. Il codice chiamante non può eseguire l'override di un ByVal meccanismo.

Se un parametro viene dichiarato con ByRef, il codice chiamante può forzare il meccanismo a ByVal racchiudere il nome dell'argomento tra parentesi nella chiamata. Per altre informazioni, vedere Procedura: Forzare un argomento da passare per valore.

L'impostazione predefinita in Visual Basic consiste nel passare 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 corrispondente ByVal. Nessun codice può modificare il valore di un elemento non modificabile.

  • Se l'elemento sottostante è modificabile, ma non si vuole che la routine possa modificare il relativo 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 procedura ha una necessità autentica di modificare l'elemento sottostante nel codice chiamante, dichiarare il parametro corrispondente ByRef.

  • Se l'esecuzione corretta del codice dipende dalla procedura che modifica l'elemento sottostante nel codice chiamante, dichiarare il parametro ByRef. Se lo si passa per valore o se il codice chiamante esegue l'override del ByRef meccanismo di passaggio racchiudendo l'argomento tra parentesi, la chiamata alla procedura potrebbe produrre risultati imprevisti.

Esempio

Descrizione

L'esempio seguente illustra quando passare argomenti per valore e quando passarli per riferimento. La procedura Calculate dispone sia di un ByVal parametro che di un ByRef parametro. Dato un tasso di interesse, ratee una somma di denaro, , debtl'attività della procedura consiste nel calcolare un nuovo valore per debt questo risultato dell'applicazione del tasso di interesse al valore originale di debt. Poiché debt è un ByRef parametro, il nuovo totale viene riflesso nel valore dell'argomento nel codice chiamante che corrisponde a debt. Il parametro rate è un ByVal parametro perché Calculate non deve modificare 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