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 argumentByVal
ä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 denByRef
.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
ellerObject
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 ByRef
kan 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ätterByRef
ö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
- Förfaranden
- Procedureparametrar och argument
- Anvisningar: Skicka argument till en procedur
- Anvisningar: Ändra värdet för ett procedurargument
- Så här: Skydda ett procedurargument mot värdeändringar
- Instruktioner: Tvinga ett argument att skickas av värde
- Skicka argument efter position och efter namn
- Värdetyper och referenstyper