Passagem de objetos usando ByVal
Quando você escreve um procedimento e quer certificar-se de que o procedimento não afetará o valor de uma variável que lhe é passada como argumento, você apenas tem que declarar o parâmetro usando a palavra ByVal. Contudo, se você declara um parâmetro do tipo objeto usando a palavra ByVal, o procedimento ainda é capaz de modificar as propriedades do objeto. Por exemplo:
Sub ZerarPedido (ByVal
Ped As CPedido)
' na próxima linha iremos mudar uma propriedade do objeto Ped,
'mesmo se ele é passado por valor
Ped.Total = 0
End Sub
Se você usar ByVal no seu programa esperando que isto protegerá o objeto passado de ser modificado pelo procedimento, você irá experimentar vários erros de lógica.
Isto não é um bug do VB, é apenas a conseqüência de variáveis de objetos serem apenas ponteiros para os dados: mesmo se um procedimento não puder mudar o valor do ponteiro passado por valor, ele ainda pode acessar (e modificar) todas as propriedades do objeto apontado por aquele ponteiro. Contudo, isto não significa que ByVal não tenha efeito quando usado com um parâmetro tipo objeto. Por exemplo, os procedimentos seguintes parecem equivalentes, mas não são:
Sub DestruirPedido (Ped As CPedido)
Set Ped = Nothing ' isto funciona
End Sub
Sub DestruirPedido2 (ByVal Ped As CPedido)
Set Ped = Nothing ' isto não
destrói o pedido original
Set Ped = New CPedido ' isto também não afeta o pedido
original
End Sub