Dela via


Skicka argument efter värde och referens (Visual Basic)

I Visual Basic kan du skicka ett argument till en procedur efter värde eller referens. Detta kallas för överföringsmekanismen och avgör om proceduren kan ändra programmeringselementet som ligger till grund för argumentet i anropskoden. Procedurdeklarationen bestämmer överföringsmekanismen för varje parameter genom att ange nyckelordet ByVal eller ByRef .

Skillnader

När du skickar ett argument till en procedur bör du vara medveten om flera olika skillnader som interagerar med varandra:

  • Om det underliggande programmeringselementet kan ändras eller inte

  • Om själva argumentet kan ändras eller inte

  • Om argumentet skickas av ett värde eller en referens

  • Om argumentdatatypen är en värdetyp eller en referenstyp

Mer information finns i Skillnader mellan ändringsbara och icke-modifierbara argument och skillnader mellan att skicka ett argument efter värde och efter referens.

Val av överföringsmekanism

Du bör välja överföringsmekanismen noggrant för varje argument.

  • Skydd. När du väljer mellan de två mekanismerna för överföring är det viktigaste kriteriet exponeringen för att anropa variabler som ska ändras. Fördelen med att skicka ett argument ByRef är att proceduren kan returnera ett värde till den anropande koden via det argumentet. Fördelen med att skicka ett argument ByVal är att det skyddar en variabel från att ändras av proceduren.

  • Prestanda. Även om överföringsmekanismen kan påverka kodens prestanda är skillnaden vanligtvis obetydlig. Ett undantag till detta är en värdetyp som har skickats ByVal. I det här fallet kopierar Visual Basic hela datainnehållet i argumentet. För en stor värdetyp, till exempel en struktur, kan det därför vara mer effektivt att skicka den ByRef.

    För referenstyper kopieras endast pekaren till data (fyra byte på 32-bitarsplattformar, åtta byte på 64-bitarsplattformar). Därför kan du skicka argument av typen String eller Object efter värde utan att skada prestanda.

Bestämning av överföringsmekanismen

Procedurdeklarationen anger överföringsmekanismen för varje parameter. Den anropande koden kan inte åsidosätta en ByVal mekanism.

Om en parameter deklareras med ByRefkan anropande kod tvinga mekanismen till genom att ByVal omsluta argumentnamnet i parenteser i anropet. Mer information finns i How to: Force an Argument to Be Passed by Value (Tvinga ett argument att skickas av värde).

Standardvärdet i Visual Basic är att skicka argument efter värde.

När du ska skicka ett argument efter värde

  • Om det anropande kodelementet som ligger till grund för argumentet är ett icke-modifierat element deklarerar du motsvarande parameter ByVal. Ingen kod kan ändra värdet för ett element som inte kan modifieras.

  • Om det underliggande elementet kan ändras, men du inte vill att proceduren ska kunna ändra dess värde, deklarerar du parametern ByVal. Endast den anropande koden kan ändra värdet för ett ändringsbart element som skickas av värdet.

När du ska skicka ett argument efter referens

  • Om proceduren har ett verkligt behov av att ändra det underliggande elementet i anropskoden deklarerar du motsvarande parameter ByRef.

  • Om rätt körning av koden beror på hur du ändrar det underliggande elementet i anropskoden deklarerar du parametern ByRef. Om du skickar det efter värde, eller om den anropande koden åsidosätter ByRef överföringsmekanismen genom att omsluta argumentet inom parenteser, kan proceduranropet ge oväntade resultat.

Exempel

beskrivning

I följande exempel visas när argumenten ska skickas efter värde och när de ska skickas med referens. Proceduren Calculate har både en ByVal och en ByRef parameter. Med tanke på en räntesats, rate, och en summa pengar, debtär uppgiften med proceduren att beräkna ett nytt värde för debt det är resultatet av att tillämpa räntan på det ursprungliga värdet för debt. Eftersom debt är en ByRef parameter återspeglas den nya summan i värdet för argumentet i den anropande koden som motsvarar debt. Parametern rate är en ByVal parameter eftersom Calculate den inte bör ändra sitt värde.

Code

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

Se även