Istruzione Function (Visual Basic)
Dichiara il nome, i parametri e il codice che definiscono una routine Function
.
Sintassi
[ <attributelist> ] [ accessmodifier ] [ proceduremodifiers ] [ Shared ] [ Shadows ] [ Async | Iterator ]
Function name [ (Of typeparamlist) ] [ (parameterlist) ] [ As returntype ] [ Implements implementslist | Handles eventlist ]
[ statements ]
[ Exit Function ]
[ statements ]
End Function
Parti
attributelist
Facoltativo. Vedere Elenco degli attributi.
accessmodifier
Facoltativo. Può essere uno dei seguenti:
Vedere Access levels in Visual Basic.
proceduremodifiers
Facoltativo. Può essere uno dei seguenti:
MustOverride Overrides
NotOverridable Overrides
Shared
Facoltativo. Vedere Shared.
Shadows
Facoltativo. Vedere Shadows.
Async
Facoltativo. Vedere Async.
Iterator
Facoltativo. Vedere Iteratore.
name
Obbligatorio. Nome della routine. Vedere Declared Element Names.
typeparamlist
Facoltativo. Elenco dei parametri di tipo (per una routine generica). Vedere Elenco tipi.
parameterlist
Facoltativo. Elenco di nomi di variabili locali che rappresentano i parametri di questa routine. Vedere Elenco parametri.
returntype
Richiesto se
Option Strict
èOn
. Tipo di dati del valore restituito da questa routine.Implements
Facoltativo. Indica che questa procedura implementa una o più routine
Function
, ognuna definita in un'interfaccia implementata dalla classe o dalla struttura contenitore di questa routine. Vedere Istruzione Implements.implementslist
Necessario se si fornisce
Implements
. Elenco delle routineFunction
implementate.implementedprocedure [ , implementedprocedure ... ]
Ogni
implementedprocedure
presenta la sintassi e le parti seguenti:interface.definedname
In parte Descrizione interface
Obbligatorio. Nome di un'interfaccia implementata da questa routine contenente la classe o la struttura. definedname
Obbligatorio. Nome mediante il quale la routine viene definita in interface
.Handles
Facoltativo. Indica che questa routine può gestire uno o più eventi specifici. Vedere Handle.
eventlist
Necessario se si fornisce
Handles
. Elenco di eventi gestiti da questa routine.eventspecifier [ , eventspecifier ... ]
Ogni
eventspecifier
presenta la sintassi e le parti seguenti:eventvariable.event
In parte Descrizione eventvariable
Obbligatorio. Variabile oggetto dichiarata con il tipo di dati della classe o della struttura che genera l'evento. event
Obbligatorio. Nome dell'evento gestito da questa routine. statements
Facoltativo. Blocco di istruzioni da eseguire all'interno di questa routine.
End Function
Termina la definizione di questa routine.
Osservazioni:
Tutto il codice eseguibile deve trovarsi all'interno di una routine. Ogni routine, a sua volta, viene dichiarata all'interno di una classe, di una struttura o di un modulo denominato classe, struttura o modulo contenitore.
Per restituire un valore al codice chiamante, utilizzare una routine Function
; in caso contrario, utilizzare una routine Sub
.
Definizione di una funzione
È possibile definire una routine Function
solo a livello di modulo. Di conseguenza, il contesto di dichiarazione per una funzione deve essere una classe, una struttura, un modulo o un'interfaccia e non può essere un file di origine, uno spazio dei nomi, una routine o un blocco. Per altre informazioni, vedere Contesti delle dichiarazioni e livelli di accesso predefiniti.
Routine Function
predefinite per l'accesso pubblico. È possibile regolare i livelli di accesso con i modificatori di accesso.
Una routine Function
può dichiarare il tipo di dati del valore restituito dalla routine. È possibile specificare qualsiasi tipo di dati o il nome di un'enumerazione, una struttura, una classe o un'interfaccia. Se non si specifica il parametro returntype
, la routine restituisce Object
.
Se in questa procedura viene utilizzata la parola chiave Implements
, anche la classe o la struttura contenitore deve avere un'istruzione Implements
che segue immediatamente la relativa istruzione Class
o Structure
. L'istruzione Implements
deve includere ogni interfaccia specificata in implementslist
. Tuttavia, il nome in base al quale un'interfaccia definisce Function
(in definedname
) non deve corrispondere al nome di questa routine (in name
).
Nota
È possibile usare espressioni lambda per definire espressioni di funzione inline. Per altre informazioni, vedere Espressioni di funzione e espressioni lambda.
Restituzione da una funzione
Quando la routine Function
torna al codice chiamante, l'esecuzione continua con l'istruzione che segue l'istruzione che ha chiamato la routine.
Per restituire un valore da una funzione, è possibile assegnare il valore al nome della funzione o includerlo in un'istruzione Return
.
L'istruzione Return
assegna contemporaneamente il valore restituito ed esce dalla funzione, come illustrato nell'esempio seguente.
Function MyFunction(ByVal j As Integer) As Double
Return 3.87 * j
End Function
L'esempio seguente assegna il valore restituito al nome della funzione myFunction
e quindi usa l'istruzione Exit Function
per restituire.
Function MyFunction(ByVal j As Integer) As Double
MyFunction = 3.87 * j
Exit Function
End Function
Le istruzioni Exit Function
e Return
causano un'uscita immediata da una routine Function
. Qualsiasi numero di istruzioni Exit Function
e Return
può essere visualizzato in qualsiasi punto della routine, ed è possibile combinare le istruzioni Exit Function
e Return
.
Se si usa Exit Function
senza assegnare un valore a name
, la routine restituisce il valore predefinito per il tipo di dati specificato in returntype
. Se returntype
non viene specificato, la routine restituisce Nothing
, ovvero il valore predefinito per Object
.
Chiamata di una funzione
Chiamare una routine Function
usando il nome della routine, seguito dall'elenco di argomenti tra parentesi, in un'espressione. È possibile omettere le parentesi solo se non si specificano argomenti. Tuttavia, il codice è più leggibile se si includono sempre le parentesi.
Si chiama una routine Function
allo stesso modo in cui si chiama qualsiasi funzione di libreria, ad esempio Sqrt
, Cos
o ChrW
.
È anche possibile chiamare una funzione usando la parola chiave Call
. In tal caso, il valore restituito viene ignorato. L'uso della parola chiave Call
non è consigliato nella maggior parte dei casi. Per altre informazioni, vedere Istruzione call.
Visual Basic talvolta riorganizzerà le espressioni aritmetiche per aumentare l'efficienza interna. Per questo motivo, non è consigliabile usare una routine Function
in un'espressione aritmetica quando la funzione modifica il valore delle variabili nella stessa espressione.
Funzioni asincrone
La funzionalità Async consente di richiamare funzioni asincrone senza usare callback espliciti o suddividere manualmente il codice tra più funzioni o espressioni lambda.
Se si contrassegna una funzione con il modificatore Async, è possibile usare l'operatore Await nella funzione. Quando il controllo raggiunge un'espressione Await
nella funzione Async
, il controllo torna al chiamante e lo stato della funzione viene sospeso fino al completamento dell'attività attesa. Al termine dell'attività, l'esecuzione può riprendere nella funzione.
Nota
Una routine Async
torna al chiamante quando incontra il primo oggetto atteso che non è ancora stato completato, oppure arriva alla fine della routine Async
, a seconda di quella che si verifica per prima.
Una funzione Async
può avere un tipo restituito di Task<TResult> o Task. Di seguito è riportato un esempio di funzione Async
con un tipo restituito di Task<TResult>.
Una funzione Async
non può dichiarare parametri ByRef.
Una istruzione sub può anche essere contrassegnata con il modificatore Async
. Viene usato principalmente per i gestori eventi, in cui non è possibile restituire un valore. Non è possibile attendere una routine Sub
Async
e il chiamante di una routine Sub
Async
non può intercettare le eccezioni generate dalla routine Sub
.
Per altre informazioni sulle funzioni di Async
, vedere Programmazione asincrona con Async e Await, Flusso di controllo in Programmi asincroni e tipi restituiti asincroni.
Funzioni iteratore
Una funzione iteratore esegue un'iterazione personalizzata su una raccolta, ad esempio un elenco o una matrice. Una funzione iteratore usa l'istruzione Yield per restituire un elemento alla volta. Quando viene raggiunta un'istruzione Yield, viene memorizzata la posizione corrente nel codice. L'esecuzione viene riavviata a partire da quella posizione la volta successiva che viene chiamata la funzione iteratore.
Per chiamare un iteratore dal codice client, usare un'istruzione For Each...Next.
Il tipo restituito di una funzione iteratore può essere IEnumerable, IEnumerable<T>, IEnumerator o IEnumerator<T>.
Per altre informazioni, vedere Iteratori.
Esempio 1
Nell'esempio seguente viene utilizzata l'istruzione Function
per dichiarare il nome, i parametri e il codice che formano il corpo di una routine Function
. Il modificatore ParamArray
consente alla funzione di accettare un numero variabile di argomenti.
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
Esempio 2
Nell'esempio seguente viene richiamata la funzione dichiarata nell'esempio precedente.
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
Esempio 3
Nell'esempio seguente, DelayAsync
è un elemento Function
Async
con tipo restituito Task<TResult>. DelayAsync
ha un'istruzione Return
che restituisce un numero intero. La dichiarazione della funzione di DelayAsync
deve quindi avere un tipo restituito Task(Of Integer)
. Poiché il tipo restituito è Task(Of Integer)
, la valutazione dell'espressione Await
in DoSomethingAsync
produce un numero intero. Questa operazione è illustrata in questa istruzione: Dim result As Integer = Await delayTask
.
La routine startButton_Click
è un esempio di routine Async Sub
. Poiché DoSomethingAsync
è una funzione Async
, deve essere attesa l'attività per la chiamata a DoSomethingAsync
, come illustrato nell'istruzione Await DoSomethingAsync()
seguente. È necessario definire la routine Sub
startButton_Click
con il modificatore Async
perché contiene un'espressione 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