Instrução Function (Visual Basic)

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

Sintaxe

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

Partes

  • attributelist

    Opcional. Veja Lista de atributo.

  • 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. Consulte Async.

  • Iterator

    Opcional. Consulte Iterator.

  • name

    Obrigatórios. O nome do procedimento. Confira Nomes de elementos declarados.

  • 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. Consulte Lista de parâmetros.

  • returntype

    Obrigatório se Option Strict for On. Tipo de dados do valor retornado por este procedimento.

  • Implements

    Opcional. Indica que este procedimento implementa um ou mais procedimentos Function, 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 Function 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 Function

    Termina a definição deste procedimento.

Comentários

Todo código executável deve estar dentro de um procedimento. Cada procedimento, por sua vez, é declarado dentro de uma classe, uma estrutura ou um módulo que é chamado de classe, estrutura ou módulo que contém.

Para retornar um valor ao código de chamada, use um procedimento Function; caso contrário, use um procedimento Sub.

Definição de uma função

Você só pode definir um procedimento Function no nível do módulo. Portanto, o contexto de declaração de uma função deve 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 Function têm como padrão o acesso público. Você pode ajustar os níveis de acesso com os modificadores de acesso.

Um procedimento Function pode declarar o tipo de dados do valor que o procedimento retorna. Você pode especificar qualquer tipo de dados ou o nome de uma enumeração, uma estrutura, uma classe ou uma interface. Se você não especificar o parâmetro returntype, o procedimento retornará Object.

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 Function (em definedname) não precisa corresponder ao nome desse procedimento (em name).

Observação

Você pode usar expressões lambda para definir expressões de função embutidas. Para obter mais informações, consulte Expressão de Função e Expressões Lambda.

Retorno de uma função

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

Para retornar um valor de uma função, você poderá atribuir o valor ao nome da função ou incluí-lo em uma instrução Return.

A instrução Return atribui simultaneamente o valor retornado e sai da função, como mostra o exemplo a seguir.

Function MyFunction(ByVal j As Integer) As Double
    Return 3.87 * j
End Function

O exemplo a seguir atribui o valor retornado ao nome da propriedade myFunction e, em seguida, usa a instrução Exit Function a ser retornada.

Function MyFunction(ByVal j As Integer) As Double
    MyFunction = 3.87 * j
    Exit Function
End Function

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

Se você usar Exit Function sem atribuir um valor a name, o procedimento retornará o valor padrão para o tipo de dados especificado em returntype. Se returntype não for especificado, o procedimento retornará Nothing, que é o valor padrão para Object.

Chamando uma Função

Você chama um procedimento Function usando o nome do procedimento, seguido pela lista de argumentos em parênteses, em uma expressão. Você só poderá omitir os parênteses se não estiver fornecendo argumentos. No entanto, seu código será mais legível se você sempre incluir os parênteses.

Você chama um procedimento Function da mesma forma que chama qualquer função de biblioteca, como Sqrt, Cosou ChrW.

Você também pode chamar uma função usando a palavra-chave Call. Nesse caso, o valor retornado é ignorado. O uso da palavra-chave Call não é recomendado na maioria dos casos. Para obter mais informações, consulte Instrução Call.

Às vezes, o Visual Basic reorganiza expressões aritméticas para aumentar a eficiência interna. Por esse motivo, você não deve usar um procedimento Function em uma expressão aritmética quando a função altera o valor das variáveis na mesma expressão.

Funções assíncronas

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 uma função com o modificador Async, você poderá usar o operador Await na função. Quando o controle atinge uma expressão Await na função Async, ele retorna para o chamador e o progresso na função é suspenso até a tarefa aguardada ser concluída. Quando a tarefa for concluída, a execução poderá ser retomada na função.

Observação

Um procedimento Async retorna para o chamador quando encontra o primeiro objeto esperado que ainda não está completo ou chega ao final do procedimento Async, o que ocorrer primeiro.

Uma função Async pode ter um tipo de retorno Task<TResult> ou Task. Um exemplo de uma função Async que tem um tipo de retorno Task<TResult> é fornecido abaixo.

Uma função Async não pode declarar parâmetros ByRef.

Uma Instrução Sub também pode ser marcada com o modificador Async. Isso é usado 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 geradas pelo procedimento Sub.

Para obter mais informações sobre as funções Async, consulte Programação assíncrona com Async e Await, Fluxo de controle em programas assíncronos e Tipos de retorno assíncronos.

Funções Iterator

Uma função iterator realiza uma iteração personalizada em uma coleção, como uma lista ou uma matriz. Um método iterator usa a instrução Yield para retornar um elemento de cada vez. Quando uma instrução Yield for atingida, o local atual no código será lembrado. A execução será reiniciada desse local na próxima vez que a função iteradora for chamada.

Você chama um iterador de um código de cliente usando uma instrução For Each…Next.

O tipo de retorno de uma função iterator pode ser IEnumerable, IEnumerable<T>, IEnumerator ou IEnumerator<T>.

Para obter mais informações, consulte Iteradores.

Exemplo 1

O exemplo a seguir usa a instrução Function para declarar o nome, os parâmetros e o código que formam o corpo de um procedimento Function. O modificador ParamArray permite que a função aceite um número variável de argumentos.

Public Function CalcSum(ByVal ParamArray args() As Double) As Double
    CalcSum = 0
    If args.Length <= 0 Then Exit Function
    For i As Integer = 0 To UBound(args, 1)
        CalcSum += args(i)
    Next i
End Function

Exemplo 2

O exemplo a seguir invoca a função declarada no exemplo anterior.

Module Module1

    Sub Main()
        ' In the following function call, CalcSum's local variables
        ' are assigned the following values: args(0) = 4, args(1) = 3,
        ' and so on. The displayed sum is 10.
        Dim returnedValue As Double = CalcSum(4, 3, 2, 1)
        Console.WriteLine("Sum: " & returnedValue)
        ' Parameter args accepts zero or more arguments. The sum
        ' displayed by the following statements is 0.
        returnedValue = CalcSum()
        Console.WriteLine("Sum: " & returnedValue)
    End Sub

    Public Function CalcSum(ByVal ParamArray args() As Double) As Double
        CalcSum = 0
        If args.Length <= 0 Then Exit Function
        For i As Integer = 0 To UBound(args, 1)
            CalcSum += args(i)
        Next i
    End Function

End Module

Exemplo 3

No exemplo a seguir, DelayAsync é um FunctionTask<TResult> que tem um tipo de retorno Async. DelayAsync tem uma instrução Return que retorna um número inteiro. Portanto, a declaração da função Task(Of Integer) deve ter um tipo de retorno DelayAsync. Como o tipo de retorno é Task(Of Integer), a avaliação da expressão Await em DoSomethingAsync produz um inteiro. Isso é demonstrado nesta instrução: 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 a DoSomethingAsyncdeve ser colocada em espera, como demonstra 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