Function (Instrucción, Visual Basic)

Declara el nombre, los parámetros y el código que definen un procedimiento Function.

Sintaxis

[ <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. Consulte Lista de atributos.

  • accessmodifier

    Opcional. Puede ser uno de los siguientes:

    Vea Access levels in Visual Basic.

  • proceduremodifiers

    Opcional. Puede ser uno de los siguientes:

  • Shared

    Opcional. Vea Shared.

  • Shadows

    Opcional. Consulte Shadows.

  • Async

    Opcional. Consulte Async.

  • Iterator

    Opcional. Vea Iterator.

  • name

    Necesario. Nombre del procedimiento. Vea Declared Element Names.

  • typeparamlist

    Opcional. Lista de parámetros de tipo para un procedimiento genérico. Consulte Lista de tipos.

  • parameterlist

    Opcional. Lista de nombres de variables locales que representan los parámetros de este procedimiento. Consulte Lista de parámetros.

  • returntype

    Obligatorio si Option Strict es On. Tipo de datos del valor devuelto por este procedimiento.

  • Implements

    Opcional. Indica que este procedimiento implementa uno o varios procedimientos Function, cada uno definido en una interfaz implementada por la clase o estructura que contiene este procedimiento. Consulte Instrucción Implements.

  • implementslist

    Es necesario si se proporciona Implements. Lista de procedimientos Function que se implementan.

    implementedprocedure [ , implementedprocedure ... ]

    Cada implementedprocedure tiene la sintaxis y las partes siguientes:

    interface.definedname

    Parte Descripción
    interface Necesario. Nombre de una interfaz implementada por la estructura o clase contenedora de este procedimiento.
    definedname Necesario. Nombre por el que se define el procedimiento en interface.
  • Handles

    Opcional. Indica que este procedimiento puede controlar uno o varios eventos específicos. Consulte Handles.

  • eventlist

    Es necesario si se proporciona Handles. Lista de eventos que controla este procedimiento.

    eventspecifier [ , eventspecifier ... ]

    Cada eventspecifier tiene la sintaxis y las partes siguientes:

    eventvariable.event

    Parte Descripción
    eventvariable Necesario. Variable de objeto declarada con el tipo de datos de la clase o estructura que genera el evento.
    event Necesario. Nombre del evento que controla este procedimiento.
  • statements

    Opcional. Bloque de instrucciones que se van a ejecutar dentro de este procedimiento.

  • End Function

    Finaliza la definición de este procedimiento.

Comentarios

Todo el código ejecutable debe estar dentro de un procedimiento. Cada procedimiento, a su vez, se declara dentro de una clase, una estructura o un módulo a los que se hace referencia como clase, estructura o módulo contenedores.

Para devolver un valor al código de llamada, use un procedimiento Function; de lo contrario, use un procedimiento Sub.

Definición de una función

Solo puede definir un procedimiento Function en el nivel de módulo. Por lo tanto, el contexto de la declaración de una función debe ser una clase, una estructura, un módulo o una interfaz y no puede ser un archivo de código fuente, un espacio de nombres, un procedimiento o un bloque. Para más información, vea Declaration Contexts and Default Access Levels (Contextos de declaración y niveles de acceso predeterminados).

El valor predeterminado de los procedimientos Function es el acceso público. Los niveles de acceso se pueden ajustar con los modificadores de acceso.

Un procedimiento Function puede declarar el tipo de datos del valor que devuelve el procedimiento. Se puede especificar cualquier tipo de datos o el nombre de una enumeración, estructura, clase o interfaz. Si no se especifica el parámetro returntype, el procedimiento devuelve Object.

Si este procedimiento usa la palabra clave Implements, la clase o estructura contenedoras también deben tener una instrucción Implements que vaya inmediatamente después de su instrucción Class o Structure. La instrucción Implements debe incluir cada interfaz especificada en implementslist. Sin embargo, el nombre por el que una interfaz define Function (en definedname) no es preciso que coincida con el nombre de este procedimiento (en name).

Nota

Puede usar expresiones lambda para definir expresiones de función insertadas. Para más información, consulte Expresiones de función y Expresiones lambda.

Devolver desde una función

Cuando el procedimiento Function vuelve al código de llamada, la ejecución continúa con la instrucción que va después de la que la llamó.

Para devolver un valor a partir de una función, puede asignar el valor al nombre de la función o incluirlo en una instrucción Return.

La instrucción Return asigna el valor devuelto y sale de la función a la vez, como se muestra en el ejemplo siguiente.

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

En el siguiente ejemplo se asigna el valor devuelto al nombre de función myFunction y, después, se usa la instrucción Exit Function para volver.

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

Las instrucciones Exit Function y Return provocan una salida inmediata de un procedimiento Function. Puede aparecer cualquier número de instrucciones Exit Function y Return en cualquier parte del procedimiento, y se pueden mezclar instrucciones Exit Function y Return.

Si se usa Exit Function sin asignar un valor a name, el procedimiento devuelve el valor predeterminado al tipo de datos que se especifica en returntype. Si returntype no se especifica, el procedimiento devuelve Nothing, que es el valor predeterminado de Object.

Llamar a una función

Llame a un procedimiento Function, para lo que debe usar su nombre, seguido de la lista de argumentos entre paréntesis, en una expresión. Los paréntesis solo se pueden omitir si no se proporciona ningún argumento. Sin embargo, el código es más legible si siempre incluye los paréntesis.

A los procedimientos de Function se les llama de la misma manera que a cualquier función de biblioteca como Sqrt, Coso ChrW.

También se puede llamar a cualquier función mediante la palabra clave Call. En ese caso, se omite el valor devuelto. En la mayoría de los casos, no se recomienda usar la palabra clave Call. Para más información, consulte Instrucción Call.

Visual Basic a veces reorganiza expresiones aritméticas para aumentar la eficacia interna. Ese es el motivo por el que no se debe usar un procedimiento Function en una expresión aritmética cuando la función cambia el valor de las variables en la misma expresión.

Funciones asincrónicas

La característica Async permite invocar funciones asincrónicas sin usar devoluciones de llamada explícitas ni dividir manualmente el código en varias funciones o expresiones lambda.

Si marca una función con el modificador Async, puede usar el operador Await en dicha función. Cuando el control accede a una expresión Await de la función Async, el control se devuelve al autor de llamada y el progreso de la función se suspende hasta que se completa la tarea esperada. Cuando esto sucede, se puede reanudar la ejecución en la función.

Nota

Un procedimiento Async vuelve al autor de la llamada cuando encuentra el primer objeto esperado que aún no se ha completado o cuando llega al final del procedimiento Async, lo que ocurra primero.

Una función Async puede tener un tipo de valor devuelto de Task<TResult> o Task. A continuación encontrará un ejemplo de función Async que tiene un tipo de valor devuelto Task<TResult>.

Una función Async no puede declarar ningún parámetro ByRef.

Una instrucción Sub también se puede marcar con el modificador Async. Se usa principalmente para controladores de eventos, donde no se puede devolver un valor. No se puede esperar un procedimiento AsyncSub y el autor de la llamada de un procedimiento AsyncSub no puede detectar las excepciones que genera el procedimiento Sub.

Para más información sobre las funciones Async, consulte Programación asincrónica con Async y Await, Controlar el flujo en los programas asincrónicos y Tipos de valor devueltos asincrónicos.

Funciones de iterador

Las funciones de iterador realizan iteraciones personalizadas en una colección, como una lista o matriz. Las funciones de iterador usan la instrucción Yield para devolver cada elemento de uno en uno. Cuando se accede a una instrucción Yield, se recuerda la ubicación actual en el código. La ejecución se reinicia desde esa ubicación la próxima vez que se llama a la función del iterador.

Llame a un iterador desde el código de cliente mediante una instrucción For Each...Next.

El tipo de valor devuelto de una función de iterador puede ser IEnumerable, IEnumerable<T>, IEnumerator o IEnumerator<T>.

Para obtener más información, consulta Iteradores.

Ejemplo 1

En el ejemplo siguiente se usa la instrucción Function para declarar el nombre, los parámetros y el código que forman el cuerpo de un procedimiento Function. El modificador ParamArray permite que la función acepte un número variable 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

Ejemplo 2

En el ejemplo siguiente se invoca la función declarada en el ejemplo 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

Ejemplo 3

En el ejemplo siguiente, DelayAsync es un AsyncFunction con un tipo de valor devuelto de Task<TResult>. DelayAsync tiene una instrucción Return que devuelve un entero. Por consiguiente, la declaración de la función de DelayAsync necesita tener un tipo de valor devuelto de Task(Of Integer). Dado que el tipo de valor devuelto es Task(Of Integer), la evaluación de la expresión Await en DoSomethingAsync genera un entero. Esto se muestra en esta instrucción: Dim result As Integer = Await delayTask.

El procedimiento startButton_Click es un ejemplo de un procedimiento Async Sub. Dado que DoSomethingAsync es una función Async, la tarea de la llamada a DoSomethingAsync debe esperar, como se muestra en la siguiente instrucción: Await DoSomethingAsync(). El procedimiento startButton_ClickSub debe definirse con el modificador Async porque el método tiene una expresión 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

Consulte también