VB .NET - Parâmetros e Argumentos - conceitos


Os termos parâmetros e argumentos são frequentemente usados de forma intercambiáveis embora eles tenham significados inteiramente diferentes.

Vamos explicar melhor...

Considere a seguinte função que replica uma string um determinado número de vezes:


    Function RepeteString(ByVal Texto As String, ByVal Contador As Integer) As String

        Dim i As Integer
        For i = 1 To Contador
            RepeteString = RepeteString & Texto
        Next
        Return RepeteString
    End Function

As variáveis Texto e Contador são os parâmetros da Função RepeteString.

Note que cada parâmetro tem um tipo de dados associado.

Agora quando você for usar esta função e a chamar, vai precisar substituir os parâmetros por variáveis, constantes ou literais.

Exemplo:

Module Module1

    Sub Main()
        Console.WriteLine(RepeteString("Mac ", 10))
        Console.ReadKey()
    End Sub

    Function RepeteString(ByVal Texto As String, ByVal Contador As Integer) As String

        Dim i As Integer
        For i = 1 To Contador
            RepeteString = RepeteString & Texto
        Next
        Return RepeteString
    End Function

End Module

Neste exemplo quando chamamos a função estamos fazendo a seguinte chamada: RepeteString("Mac ", 10)

Os itens "Mac" e 10 que nós usamos no lugar dos parâmetros são chamados argumentos.

Então temos:

  1. Function RepeteString(ByVal Texto As String, ByVal Contador As Integer) As String -> Parâmetros = Texto e Contador
  2. Console.WriteLine(RepeteString("Mac ", 10)) -> Argumentos = "Mac" e 10

Passando argumentos

Os Argumentos podem ser passados para uma função de dois modos: por valor ou por referência.

Muitas vezes a passagem de argumentos é confundido com a passagem de parâmetros, embora seja os argumentos e não os parâmetros que estão sendo passados.

A declaração o procedimento RepeteString dada no início contém a palavra-chave ByVal na frente de cada um dos parâmetros. Isto especifica que os argumentos são passados por valor para esta função. Passar por valor significa que o valor real do argumento é passado para a função. Isso é relevante quando um argumento é uma variável.

Veja este exemplo:

Public Class Form1

Dim idade As Integer = 20

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    Incrementa(idade)
    MsgBox(idade)
End Sub

Sub Incrementa(ByVal x As Integer)
   x = x + 1
End Sub


End Class

O resultado exibido é o valor 20 o que significa que a linha de código :   Incrementa(idade)

Não esta fazendo nada.

A razão é que o argumento idade é passado para o procedimento Incrementa por valor (ByVal).

Desde que somente o valor (neste caso 20) é passado, esse valor é atribuído a uma variável local chamada x dentro da função.

Esta variável local x é aumentada para 21, mas uma vez que o procedimento termina, a variável local x é destruída.

Conclusão : A variável idade não é passada para o procedimento logo e o seu valor não é alterado.

Vamos modificar o código alterando a definição do procedimento Incrementa, substituindo ByVal por ByRef.

Sub Incrementa(ByRef x As Integer)
   x = x + 1
End Sub

Ao executarmos o código novamente o resultado será diferente...

Neste caso que esta sendo passado para o procedimento Incrementa é uma referência ao argumento idade.

Daí, o procedimento na verdade opera na variável passado para ele, incrementando o valor de idade para 21.

Falando de outra forma, a variável representada pelo parâmetro x e na verdade a variável idade que foi passada para o procedimento.

No VB .NET , o método padrão de passagem de argumentos é Por Valor (ByVal).

Nota: nas primeiras versões da linguagem Visual Basic a passagem de argumentos padrão era feita por referência.

Passando Objetos

Há uma sutileza na passagem de argumentos com parâmetros de qualquer tipo de objeto.

A sutileza ocorre porque uma variável objeto é um ponteiro, isto é, ela contém uma referência ao (ou o endereço do) objeto.

Se passarmos uma variável objeto, estamos passando o conteúdo da variável, o qual é o endereço do objeto.

Assim, qualquer alteração feita na chamada do procedimento afeta o próprio objeto, não a cópia do objeto.

Esta parece ser a passagem feita por referência, mas não é.

Pense desta forma: passando a valor do endereço de um objeto é como passar uma referência ao objeto.

Por outro lado, se passarmos uma variável objeto por referência, estamos passando o endereço da variável.

Em outras palavras, estamos passando o endereço do endereço do objeto.

Em linguagens que suportam ponteiros isto é referido como um duplo ponteiro.

Vamos ilustrar com um exemplo.

Considere o seguinte código, e imagine que o formulário contendo esse código tem duas caixas de texto: TextBox1 com o texto "TextBox1" e TextBox2 com o texto "TextBox2":

  Public Function GetTexto(ByVal txt As TextBox) As String
        ' Muda a referencia para o textbox
        txt = TextBox2
        Return txt.ToString
    End Function

    Sub FazAlgumaCoisa()
        Dim t As TextBox
        t = TextBox1
        GetTexto(t)
        MsgBox(t.Text) ' Exibe TextBox1 quando usamos ByVal e TextBox2 quando usamos ByRef
    End Sub

Vamos analisar em detalhes o que acontece quando executamos o procedimento FazAlgumaCoisa():

1- A passagem é feita por valor (ByVal)

O conteúdo do objeto TextBoxa é atribuida a t:

A função GetTexto é chamada, passando t por valor.

A variável t contém o valor do objeto TextBox1.

Mas o argumento passado por valor recebe o conteúdo do objeto TextBox2 : txt = TextBox2 sendo retornado para o procedimento;

Na última linha de código temos a exibição do conteúdo da variável t que é "TextBox1".

2- A passagem é feita por referência (ByRef)

Neste caso a função GetTexto é chamada passando t por referência.

Agora o argumento t passado por referência contém o endereço da variável e não o seu valor. Dessa forma txt é t que recebe o valor do objeto TextBox2.

O retorno da função é o valor de t que é o mesmo que txt cujo valor agora é "TextBox2"

Argumentos Opcionais

No VB .NET os parâmetros podem ser declarados como opcionais usando a palavra chave Opcional, como mostrado no seguinte código: Sub Calcular(Optional ByVal Switch As Boolean = False)

Os parâmetros opcionais devem ser declarados com o valor padrão o qual é passado para o procedimento se o programa chamador não fornecer o valor deste parâmetro.

As seguintes regras se aplicam aos argumentos opcionais:

Note que em versões anteriores do VB, você podia omitir o valor padrão e, se o parâmetro fosse do tipo Variant, você podia usar a função IsMissing para determinar se um valor tinha sido fornecido. Isto não é possível no VB. NET, e a função IsMissing não é mais suportada.

Usando ParamArray

Normalmente, uma definição de procedimento especifica um número fixo de parâmetros. No entanto, a palavra-chave ParamArray que indica uma matriz de parâmetros, nos permite declarar um procedimento com um número indeterminado de parâmetros.

Portanto, cada chamada para o procedimento pode utilizar um número diferente de parâmetros.

Suponhamos, por exemplo, que queremos definir uma função para tirar a média de uma série de resultados de testes, mas o número de resultados pode variar.

Então vamos declarar a função usando ParamArray da seguinte forma:

    Function GetMedia(ByVal ParamArray Resultados() As Single) As Single
        Dim i As Integer
        For i = 0 To UBound(Resultados)
            GetMedia = GetMedia + CSng(Resultados(i))
        Next
        GetMedia = GetMedia / (UBound(Resultados) + 1)
    End Function

Agora podemos fazer chamadas a essa função variando o número de argumentos: MsgBox(GetMedia(1, 2, 3, 4, 5)) ou MsgBox(GetMedia(1, 2, 3)) ou MsgBox(GetMedia(1, 2, 3, 4))

As seguintes regras aplicam-se à utilização de ParamArray:

· Um procedimento só pode ter uma matriz de parâmetro, e deve ser o último parâmetro no procedimento.
· A matriz de parâmetro deve ser passada por valor, e você deve incluir explicitamente ByVal no procedimento de definição.
· A matriz de parâmetro deve ser uma matriz unidimensional. Se o tipo não é declarado, é assumido como object.
· A matriz de parâmetros é automaticamente opcional. Seu valor padrão é uma matriz de parâmetros vazia unidimensional do tipo dados da matriz dos parâmetro.

Referências:


José Carlos Macoratti