Passando argumentos por valor e por referência (Visual Basic)
No Visual Basic, você pode passar um argumento para um procedimento por valor ou por referência. Isso é conhecido como mecanismo de passagem e determina se o procedimento pode modificar o elemento de programação subjacente ao argumento no código de chamada. A declaração de procedimento determina o mecanismo de passagem para cada parâmetro especificando a palavra-chave ByVal ou ByRef .
Distinções
Ao passar um argumento para um procedimento, esteja ciente de várias distinções diferentes que interagem entre si:
Se o elemento de programação subjacente é modificável ou não modificável
Se o argumento em si é modificável ou não modificável
Se o argumento está sendo passado por valor ou por referência
Se o tipo de dados de argumento é um tipo de valor ou um tipo de referência
Para obter mais informações, consulte Diferenças entre argumentos modificáveis e não modificáveis e Diferenças entre passar um argumento por valor e por referência.
Escolha do mecanismo de passagem
Você deve escolher o mecanismo de passagem cuidadosamente para cada argumento.
Proteção. Na escolha entre os dois mecanismos de passagem, o critério mais importante é a exposição das variáveis de chamada à mudança. A vantagem de passar um argumento
ByRef
é que o procedimento pode retornar um valor para o código de chamada por meio desse argumento. A vantagem de passar um argumentoByVal
é que ele protege uma variável de ser alterada pelo procedimento.Desempenho. Embora o mecanismo de passagem possa afetar o desempenho do seu código, a diferença geralmente é insignificante. Uma exceção a isso é um tipo de valor passado
ByVal
. Nesse caso, o Visual Basic copia todo o conteúdo de dados do argumento. Portanto, para um tipo de valor grande, como uma estrutura, pode ser mais eficiente passá-loByRef
.Para tipos de referência, apenas o ponteiro para os dados é copiado (quatro bytes em plataformas de 32 bits, oito bytes em plataformas de 64 bits). Portanto, você pode passar argumentos do tipo
String
ouObject
por valor sem prejudicar o desempenho.
Determinação do mecanismo de passagem
A declaração de procedimento especifica o mecanismo de passagem para cada parâmetro. O código de chamada não pode substituir um ByVal
mecanismo.
Se um parâmetro for declarado com ByRef
, o código de chamada pode forçar o mecanismo colocando ByVal
o nome do argumento entre parênteses na chamada. Para obter mais informações, consulte Como forçar um argumento a ser passado por valor.
O padrão no Visual Basic é passar argumentos por valor.
Quando passar um argumento por valor
Se o elemento de código de chamada subjacente ao argumento for um elemento não modificável, declare o parâmetro correspondente ByVal. Nenhum código pode alterar o valor de um elemento não modificável.
Se o elemento subjacente for modificável, mas você não quiser que o procedimento possa alterar seu valor, declare o parâmetro
ByVal
. Somente o código de chamada pode alterar o valor de um elemento modificável passado pelo valor.
Quando passar um argumento por referência
Se o procedimento tiver uma necessidade genuína de alterar o elemento subjacente no código de chamada, declare o parâmetro correspondente ByRef.
Se a execução correta do código depender do procedimento que altera o elemento subjacente no código de chamada, declare o parâmetro
ByRef
. Se você passá-lo por valor, ou se o código de chamada substituir oByRef
mecanismo de passagem colocando o argumento entre parênteses, a chamada de procedimento poderá produzir resultados inesperados.
Exemplo
Description
O exemplo a seguir ilustra quando passar argumentos por valor e quando passá-los por referência. O procedimento Calculate
tem um ByVal
e um ByRef
parâmetro. Dada uma taxa de juro, rate
e uma soma de dinheiro, debt
a tarefa do procedimento é calcular um novo valor para debt
que é o resultado da aplicação da taxa de juro ao valor original de debt
. Como debt
é um ByRef
parâmetro, o novo total é refletido no valor do argumento no código de chamada que corresponde a debt
. Parâmetro rate
é um ByVal
parâmetro porque Calculate
não deve alterar seu valor.
Código
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
Consulte também
- Procedimentos
- Parâmetros e argumentos do procedimento
- Como: Passar argumentos para um procedimento
- Como alterar o valor de um argumento de procedimento
- Como: Proteger um argumento de procedimento contra alterações de valor
- Como: Forçar um argumento a ser passado por valor
- Passando argumentos por posição e por nome
- Tipos de valor e tipos de referência