Visual Basic, VB .NET, ASP, Active X, Access, SQL Server

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