Instrução Sub (Visual Basic)

Declara o nome, os parâmetros e o código que definem um procedimento Sub.

Sintaxe

[ <attributelist> ] [ Partial ] [ accessmodifier ] [ proceduremodifiers ] [ Shared ] [ Shadows ] [ Async ]
Sub name [ (Of typeparamlist) ] [ (parameterlist) ] [ Implements implementslist | Handles eventlist ]
    [ statements ]
    [ Exit Sub ]
    [ statements ]
End Sub

Partes

  • attributelist

    Opcional. Veja Lista de atributo.

  • Partial

    Opcional. Indica a definição de um método parcial. Confira métodos parciais.

  • accessmodifier

    Opcional. Um dos seguintes pode ser feito:

    Consulte Níveis de acesso no Visual Basic.

  • proceduremodifiers

    Opcional. Um dos seguintes pode ser feito:

  • Shared

    Opcional. Consulte Shared.

  • Shadows

    Opcional. Confira Sombras.

  • Async

    Opcional. Confira Async.

  • name

    Obrigatórios. O nome do procedimento. Confira Nomes de elementos declarados. Para criar um procedimento de construtor para uma classe, defina o nome de um procedimento Sub como a palavra-chave New. Para obter mais informações, confira Tempo de vida do objeto: como os objetos são criados e destruídos.

  • typeparamlist

    Opcional. Lista de parâmetros de tipo para um procedimento genérico. Confira Lista de tipos.

  • parameterlist

    Opcional. Lista de nomes de variáveis locais que representam os parâmetros deste procedimento. Confira a Lista de parâmetros.

  • Implements

    Opcional. Indica que este procedimento implementa um ou mais procedimentos Sub, cada um definido em uma interface implementada pela classe ou estrutura que contém esse procedimento. Consulte Instrução Implements.

  • implementslist

    Necessário se Implements for fornecido. Lista de procedimentos Sub que estão sendo implementados.

    implementedprocedure [ , implementedprocedure ... ]

    Cada implementedprocedure tem a sintaxe e as partes a seguir:

    interface.definedname

    Parte Descrição
    interface Obrigatórios. Nome de uma interface implementada pela classe ou estrutura que contém este procedimento.
    definedname Obrigatórios. Nome pelo qual o procedimento é definido em interface.
  • Handles

    Opcional. Indica que esse procedimento pode lidar com um ou mais eventos específicos. Consulte Identificadores.

  • eventlist

    Necessário se Handles for fornecido. Lista de eventos que este procedimento manipula.

    eventspecifier [ , eventspecifier ... ]

    Cada eventspecifier tem a sintaxe e as partes a seguir:

    eventvariable.event

    Parte Descrição
    eventvariable Obrigatórios. Variável de objeto declarada com o tipo de dados da classe ou estrutura que gera o evento.
    event Obrigatórios. Nome do evento que este procedimento manipula.
  • statements

    Opcional. Bloco de instruções a serem executadas dentro deste procedimento.

  • End Sub

    Encerra a definição deste procedimento.

Comentários

Todo código executável deve estar dentro de um procedimento. Use um procedimento Sub quando não quiser retornar um valor para o código de chamada. Use um procedimento Function quando quiser retornar um valor.

Definindo um procedimento Sub

Você pode definir um procedimento Sub somente no nível do módulo. O contexto de declaração de um procedimento Sub deve, portanto, ser uma classe, uma estrutura, um módulo ou uma interface e não pode ser um arquivo de origem, um namespace, um procedimento ou um bloco. Para obter mais informações, consulte Contextos de declaração e níveis de acesso padrão.

Os procedimentos Sub têm como padrão o acesso público. Você pode ajustar seus níveis de acesso usando os modificadores de acesso.

Se o procedimento usar a palavra-chave Implements, a classe ou estrutura que contém deverá ter uma instrução Implements que siga imediatamente sua instrução Class ou Structure. A instrução Implements deve incluir cada interface especificada em implementslist. No entanto, o nome pelo qual uma interface define o Sub (em definedname) não precisa corresponder ao nome desse procedimento (em name).

Retornando de um procedimento Sub

Quando um procedimento Sub retorna ao código de chamada, a execução continua com a instrução após a instrução que o chamou.

O exemplo a seguir mostra um retorno de um procedimento Sub.

Sub mySub(ByVal q As String)
    Return
End Sub

As instruções Exit Sub e Return causam uma saída imediata de um procedimento Sub. Qualquer número de instruções Exit Sub e Return podem aparecer em qualquer lugar no procedimento, e você pode misturar instruções Exit Sub e Return.

Chamando um procedimento Sub

Você chama um procedimento Sub usando o nome do procedimento em uma instrução e, em seguida, segue esse nome com sua lista de argumentos em parênteses. Você só poderá omitir os parênteses se não fornecer argumentos. No entanto, seu código será mais legível se você sempre incluir os parênteses.

Um procedimento Sub e um procedimento Function podem ter parâmetros e executar uma série de instruções. No entanto, um procedimento Function retorna um valor e um procedimento Sub não. Portanto, você não pode usar um procedimento Sub em uma expressão.

Você pode usar a palavra-chave Call ao chamar um procedimento Sub, mas essa palavra-chave não é recomendada para a maioria dos usos. Para obter mais informações, confira Instrução Call.

Às vezes, o Visual Basic reorganiza expressões aritméticas para aumentar a eficiência interna. Por esse motivo, se sua lista de argumentos incluir expressões que chamam outros procedimentos, você não deve assumir que essas expressões serão chamadas em uma ordem específica.

Procedimentos Sub assíncronos

Usando o recurso async, você pode invocar funções assíncronas sem usar retornos de chamada explícitos ou dividir manualmente seu código entre várias funções ou expressões lambda.

Se marcar um procedimento com o modificador Async, você poderá usar o operador Await no procedimento. Quando o controle atinge uma expressão Await no procedimento Async, o controle retorna para o chamador e o progresso no procedimento é suspenso até a tarefa aguardada ser concluída. Quando a tarefa for concluída, a execução poderá ser retomada no procedimento.

Observação

Um procedimento Async retorna para o chamador quando o primeiro objeto esperado que ainda não está completo é encontrado ou quando é atingido o fim do procedimento Async, o que ocorrer primeiro.

Você também pode marcar uma Instrução de Função com o modificador Async. Uma função Async pode ter um tipo de retorno de Task<TResult> ou Task. Um exemplo mais adiante neste tópico mostra uma função Async que tem um tipo de retorno de Task<TResult>.

Os procedimentos AsyncSub são usados principalmente para manipuladores de eventos, em que um valor não pode ser retornado. Um procedimento AsyncSub não pode ser aguardado e o chamador de um procedimento AsyncSub não pode capturar exceções que o procedimento Sub gera.

Um procedimento Async não pode declarar nenhum parâmetro ByRef.

Para obter mais informações sobre os procedimentos Async, confira Programação assíncrona com async e await, Fluxo de controle em programas assíncronos e Tipos de retorno assíncronos.

Exemplo 1

O exemplo a seguir usa a instrução Sub para definir o nome, os parâmetros e o código que formam o corpo de um procedimento Sub.

Sub ComputeArea(ByVal length As Double, ByVal width As Double)
    ' Declare local variable.
    Dim area As Double
    If length = 0 Or width = 0 Then
        ' If either argument = 0 then exit Sub immediately.
        Exit Sub
    End If
    ' Calculate area of rectangle.
    area = length * width
    ' Print area to Immediate window.
    Debug.WriteLine(area)
End Sub

Exemplo 2

No exemplo a seguir, DelayAsync é um AsyncFunction que tem um tipo de retorno de Task<TResult>. DelayAsync tem uma instrução Return que retorna um número inteiro. Portanto, a declaração da função de Task(Of Integer) deve ter um tipo de retorno de DelayAsync. Como o tipo de retorno é Task(Of Integer), a avaliação da expressão Await em DoSomethingAsync produz um inteiro, como a instrução a seguir demonstra: Dim result As Integer = Await delayTask.

O procedimento startButton_Click é um exemplo de um procedimento Async Sub. Como DoSomethingAsync é uma função Async, a tarefa para a chamada para DoSomethingAsync deve ser colocada em espera, como mostra a seguinte instrução: Await DoSomethingAsync(). O procedimento startButton_ClickSub deve ser definido com o modificador Async porque ele tem uma expressão Await.

' Imports System.Diagnostics
' Imports System.Threading.Tasks

' This Click event is marked with the Async modifier.
Private Async Sub startButton_Click(sender As Object, e As RoutedEventArgs) Handles startButton.Click
    Await DoSomethingAsync()
End Sub

Private Async Function DoSomethingAsync() As Task
    Dim delayTask As Task(Of Integer) = DelayAsync()
    Dim result As Integer = Await delayTask

    ' The previous two statements may be combined into
    ' the following statement.
    ' Dim result As Integer = Await DelayAsync()

    Debug.WriteLine("Result: " & result)
End Function

Private Async Function DelayAsync() As Task(Of Integer)
    Await Task.Delay(100)
    Return 5
End Function

'  Output:
'   Result: 5

Confira também