Compartilhar via


Solucionando problemas de procedimentos (Visual Basic)

Esta página lista somente problemas comuns que podem ocorrer quando se trabalha com procedimentos.

Retornando um tipo arrayde uma função de procedimento

Se um procedimento Function retornar um tipo de dados array, você não pode usar o nome Function para armazenar os valores nos elementos do array. Se você tentar fazer isso, o compilador interpretará como uma chamada para Function. O exemplo a seguir gera Erros de compilador.

Function allOnes(ByVal n As Integer) As Integer()

For i As Integer = 1 To n - 1

' The following statement generates a COMPILER ERROR.

allOnes(i) = 1

Next i

' The following statement generates a COMPILER ERROR.

Return allOnes()

End Function

A declaração allOnes(i) = 1 gera um erro do compilador porque ela aparenta chamar allOnes com um argumento do tipo de dados incorreto (um singleton Integer em vez de um array Integer). A declaração Return allOnes() gera um erro do compilador porque ela aparenta chamar allOnes com nenhum argumento.

Abordagem correta: Para modificar os elementos de um array que está para ser retornado, defina um array interno como uma variável local. O exemplo a seguir compila sem erro.

Function allOnes(ByVal n As Integer) As Integer()
    Dim i As Integer, iArray(n) As Integer 
    For i = 0 To n - 1
        iArray(i) = 1
    Next i
    Return iArray
End Function

Argumento não sendo modificado pela chamada de procedimento

Se você pretende permitir que um procedimento altere um elemento de programação subjacente a um argumento no código de chamada, você deve passá-lo por referência. Mas um procedimento pode acessar os elementos de um argumento de tipo de referência mesmo se você passá-lo por valor.

  • Variável Subjacente . Para permitir que o procedimento substitua o valor do elemento variável subjacente, o procedimento deve declarar o parâmetro ByRef (Visual Basic). Aém disso, o código de chamada não deve colocarc o argumento entre parênteses, porque isso poderia substituir o mecanismo de passagem ByRef.

  • Elementos de Tipo de Referência Se você declarar um parâmetro ByVal (Visual Basic), o procedimento não pode modificar o elemento variável subjacente. No entanto, se o argumento for um tipo de referência, o procedimento pode modificar os membros do objeto para o qual ele aponta, mesmo que não seja possível substituir o valor da variável. Por exemplo, se o argumento for uma variável array, o procedimento não pode atribuir um novo array a ela, mas ele pode alterar um ou mais dos seus elementos. Os elementos alterados são refletidos na variável array subjacente no código de chamada.

O exemplo a seguir defeine dois procedimentos que tenham uma variável de matriz e operam em seus elementos. O procedimento increase simplesmente adiciona um para cada elemento. O procedimento replace atribui o parâmetro a() uma nova matriz e, em seguida, adiciona um para cada elemento. No entanto, a reatribuição não afeta a variável array subjacente no código de chamada porque a() é declarado como ByVal.

Public Sub increase(ByVal a() As Long)
    For j As Integer = 0 To UBound(a)
        a(j) = a(j) + 1
    Next j
End Sub
Public Sub replace(ByVal a() As Long)
    Dim k() As Long = {100, 200, 300}
    a = k
    For j As Integer = 0 To UBound(a)
        a(j) = a(j) + 1
    Next j
End Sub

O exemplo a seguir faz chamadas para increase e replace.

Dim n() As Long = {10, 20, 30, 40}
Call increase(n)
MsgBox("After increase(n): " & CStr(n(0)) & ", " & 
    CStr(n(1)) & ", " & CStr(n(2)) & ", " & CStr(n(3)))
Call replace(n)
MsgBox("After replace(n): " & CStr(n(0)) & ", " & 
    CStr(n(1)) & ", " & CStr(n(2)) & ", " & CStr(n(3)))

Exibe o primeiro MsgBox chamada " após increase(n): 11 21, 31, 41". Como n é um tipo de referência, increase pode alterar seus membros, mesmo que ele seja passado ByVal.

A segunda MsgBox chamada exibe " Após Replace(n): 11, 21, 31, 41. Como n é passado ByVal,replace não pode modificar a variável n atribuindo um novo array a ela. Quando replace cria a nova instância de array k e a atribui para a variável local a,ele perde a referência à n passada pelo código de chamada. Quando ele aumenta os membros do a, somente o array ocal k é afetado.

Abordagem correta: Para modificar um elemento variável subjacente, passá-lo por referência. O exemplo a seguir mostra a alteração na declaração de replace que permite que ele substitua um array com outro no código de chamada.

Public Sub replace(ByRef a() As Long)

Não é possível definir uma sobrecarga

Se você quiser definir uma versão sobrecarregada de um procedimento, você deve usar o mesmo nome mas uma assinatura diferente. Se o compilador não pode diferenciar sua declaração de uma sobrecarga com a mesma assinatura, ele gera um erro.

A assinatura de um procedimento é determinada pelo nome do procedimento e a lista de parâmetros. Cada sobrecarga deve ter o mesmo nome de todas as outras sobrecargas, mas deve diferir de todoa elas em pelo menos um dos outros componentes da assinatura. Para obter mais informações, consulte Sobrecarga de procedimento (Visual Basic).

Os itens a seguir, mesmo que pertençam à lista de parâmetros, não são componentes da assinatura de um procedimento:

  • Palavras-chave modificadores de procedimento, como Public, Shared, e Static

  • Nomes de parâmetro

  • Palavras-chave modificadoras de parâmetros (como ByRef e Optional)

  • O tipo de dado do valor de retorno (exceto para um operador de conversão)

Você não pode sobrecarregar um procedimento, variando apenas um ou mais dos itens anteriores.

Abordagem correta: Para conseguir definir uma sobrecarga procedimento, você deve variar a assinatura. Como você deve usar o mesmo nome, você deve variar o número, ordem ou tipos de dados dos parâmetros. Em um procedimento genérico, você pode variar o número de parâmetros de tipo. Em um operador de conversão (Função CType (Visual Basic)), você pode variar o tipo de retorno.

Resolução de sobrecarga com argumentos Opcional e ParamArray

Se você estiver sobrecarregando um procedimento com um ou mais parâmetros Opcional (Visual Basic) ou um parâmetro ParamArray (Visual Basic) , você deve evitar duplicar qualquer uma das sobrecargas implícitas. Para obter mais informações, consulte: Considerações sobre procedimentos de sobrecarga (Visual Basic).

Chamando uma versão incorreta de um procedimento sobrecarregado

Se um procedimento tem várias versões sobrecarregadas, você deve estar familiarizado com todos as suas listas de parâmetros e entender como Visual Basic resolve chamadas entre as sobrecargas. Caso contrário, você poderia chamar uma sobrecarga diferente daquela pretendida.

Quando você determinar que sobrecarga você deseja chamar, tenha cuidado para observar as seguintes regras:

  • Forneça o número correto de argumentos e na ordem correta.

  • Idealmente, seus argumentos devem ter os mesmos tipos de dados que os parâmetros correspondentes. Em qualquer caso, o tipo de dados de cada argumento deve ampliar ao de seu parâmetro correspondente. Isso é verdadeiro mesmo com o Instrução Option Strict definido como Off. Se uma sobrecarga exigir qualquer conversão de restrição na sua lista de argumentos, a sobrecarga não está qualificada a ser chamada.

  • Se você fornecer argumentos que exigem conversões de ampliação, faça com que seus tipos sejam o mais próximo possível dos tipos de dados dos parâmetros correspondentes. Se duas ou mais sobrecargas aceitarem os tipos de dados dos seus argumentos, o compilador resolve a chamada para a sobrecarga que precisa do mínimo de ampliação.

Você pode reduzir a chance de diferenças de tipo de dado usando a palavra-chave de conversão Função CType (Visual Basic) ao preparar seus argumentos.

Falha de Resolução de Sobrecarga

Quando você chamar um procedimento sobrecarregado, o compilador tenta eliminar todas menos uma das sobrecargas. Se ele for bem-sucedido, ele resolve a chamada para essa sobrecarga. Se ele elimina todas as sobrecargas, ou se não é possível reduzir as sobrecargas qualificadas para uma única candidata, ele gera um erro.

O exemplo a seguir ilustra o processo de resolução de sobrecarga.

Overloads Sub z(ByVal x As Byte, ByVal y As Double)
End Sub 
Overloads Sub z(ByVal x As Short, ByVal y As Single)
End Sub 
Overloads Sub z(ByVal x As Integer, ByVal y As Single)
End Sub
Dim r, s As Short 
Call z(r, s)
Dim p As Byte, q As Short 
' The following statement causes an overload resolution error. 
Call z(p, q)

Na primeira chamada, o compilador elimina o primeiro sobrecarregamento porque o tipo do primeiro argumento (Short) estreita ao tipo do parâmetro correspondente (Byte). Então elimina o terceiro sobrecarregamento porque cada tipo de argumento no segundo sbrecarregamento (Short e Single) alarga ao tipo correspondente no terceiro sobrecarregamento (Integer e Single). O segundo sobrecarregamento requer menos alargamento, então o compilador usa-o para a chamada.

Na segunda chamada, o compilador não pode eliminar qualquer dos sobrecarregamentos na base do estreitamento. Elimina o terceiro sobrecarregamento pela mesma razão que na primeira chamada, porque pode chamar o segundo sobrecarregamento com menos alargamento de tipos de argumento. Entretanto, o compilador não pode resolver entre o primeiro e segundo sobrecarregamentos. Cada um possui tipo definido de parâmetro que alarga para o tipo correspondente no outro (Byte a Short, mas Single a Double). O compilador, por isso, gera um erro de resolução de sobrecarregamento.

Abordagem correta: Para chamar um procedimento sobrecarregado sem ambiguidade, use Função CType (Visual Basic) para haver correspondência entre os tipos de dados dos argumento e os tipos de dados dos parâmetros. O exemplo a seguir mostra uma chamada para z que força a resolução para a segunda sobrecarga.

Call z(CType(p, Short), CType(q, Single))

Resolução de sobrecarga com argumentos Opcional e ParamArray

Se duas sobrecargas de um procedimento tenham assinaturas idênticas exceto pelo fato de que o último parâmetro é declarado Opcional (Visual Basic) em um e ParamArray (Visual Basic) no outro, o compilador resolve a chamada para o procedimento de acordo com a correspondência mais próxima. Para obter mais informações, consulte Resolução de sobrecarga (Visual Basic).

Consulte também

Conceitos

Procedimentos no Visual Basic

Subprocedimentos (Visual Basic)

Procedimentos de função (Visual Basic)

Procedimentos de propriedade (Visual Basic)

Procedimentos do operador (Visual Basic)

Parâmetros e argumentos de procedimento (Visual Basic)

Sobrecarga de procedimento (Visual Basic)

Considerações sobre procedimentos de sobrecarga (Visual Basic)

Resolução de sobrecarga (Visual Basic)