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:
proceduremodifiers
Opcional. Puede ser uno de los siguientes:
MustOverride Overrides
NotOverridable Overrides
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
esOn
. 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 procedimientosFunction
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
, Cos
o 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 Async
Sub
y el autor de la llamada de un procedimiento Async
Sub
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 elemento Async
Function
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_Click
Sub
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