Function 语句 (Visual Basic)
声明定义 Function
过程的名称、参数和代码。
语法
[ <attributelist> ] [ accessmodifier ] [ proceduremodifiers ] [ Shared ] [ Shadows ] [ Async | Iterator ]
Function name [ (Of typeparamlist) ] [ (parameterlist) ] [ As returntype ] [ Implements implementslist | Handles eventlist ]
[ statements ]
[ Exit Function ]
[ statements ]
End Function
组成部分
attributelist
可选。 请参阅特性列表。
accessmodifier
可选。 可以是以下值之一:
proceduremodifiers
可选。 可以是以下值之一:
MustOverride Overrides
NotOverridable Overrides
Shared
可选。 请参阅 Shared。
Shadows
可选。 请参阅 Shadows。
Async
可选。 请参阅 Async。
Iterator
可选。 请参阅 Iterator。
name
必需。 过程的名称。 请参阅 Declared Element Names。
typeparamlist
可选。 泛型过程的类型参数列表。 请参阅类型列表。
parameterlist
可选。 表示此过程的参数的局部变量名称列表。 请参阅参数列表。
returntype
如果
Option Strict
为On
,则是必需的。 此过程返回的值的数据类型。Implements
可选。 表示该过程实现了一个或多个
Function
过程,每个过程都在由该过程的包含类或结构实现的接口中定义。 请参阅 Implements 语句。implementslist
如果提供
Implements
,则是必需的。 所实现的Function
过程的列表。implementedprocedure [ , implementedprocedure ... ]
每个
implementedprocedure
都具有以下语法和部件:interface.definedname
组成部分 说明 interface
必需。 此过程的包含类或结构所实现的接口的名称。 definedname
必需。 在 interface
中用于定义过程的名称。Handles
可选。 表示此过程可以处理一个或多个特定事件。 请参阅 Handles。
eventlist
如果提供
Handles
,则是必需的。 此过程处理的事件列表。eventspecifier [ , eventspecifier ... ]
每个
eventspecifier
都具有以下语法和部件:eventvariable.event
组成部分 说明 eventvariable
必需。 使用引发事件的类或结构的数据类型声明的对象变量。 event
必需。 此过程处理的事件的名称。 statements
可选。 要在此过程中执行的语句块。
End Function
终止此过程的定义。
注解
所有可执行代码都必须位于某一过程中。 每个过程进而在类、结构或模块(称为包含类、结构或模块)中进行声明。
若要将值返回到调用代码,请使用 Function
过程;否则使用 Sub
过程。
定义函数
你只能在模块级别定义 Function
过程。 因此,函数的声明上下文必须是类、结构、模块或接口,不能是源文件、命名空间、过程或块。 有关详细信息,请参阅声明上下文和默认访问级别。
Function
过程默认为公共访问。 可以使用访问修饰符调整其访问级别。
Function
过程可以声明过程返回的值的数据类型。 你可以指定任何数据类型或是枚举、结构、类或接口的名称。 如果未指定 returntype
参数,则过程返回 Object
。
如果此过程使用 Implements
关键字,则包含的类或结构必须还有一个紧跟在 Class
或 Structure
语句后的 Implements
语句。 Implements
语句必须包括在 implementslist
中指定的每个接口。 但是,接口用于定义 Function
的名称(在 definedname
中)无需与此过程的名称(在 name
中)相同。
注意
可以使用 lambda 表达式定义内联函数表达式。 有关详细信息,请参阅函数表达式和 Lambda 表达式。
从函数返回
当 Function
过程返回到调用代码时,会继续执行紧跟在调用该过程的语句后的语句。
要从函数返回值,你可以将值分配给函数名称或将其包含在 Return
语句中。
Return
语句会同时分配返回值并退出函数,如以下示例所示。
Function MyFunction(ByVal j As Integer) As Double
Return 3.87 * j
End Function
以下示例将返回值分配给函数名称 myFunction
,然后使用 Exit Function
语句返回。
Function MyFunction(ByVal j As Integer) As Double
MyFunction = 3.87 * j
Exit Function
End Function
Exit Function
和 Return
语句将导致立即退出 Function
过程。 任意数量的 Exit Function
和 Return
语句可以出现在过程中的任何位置,并且你可以混合使用 Exit Function
和 Return
语句。
如果你在没有为 name
赋值的情况下使用 Exit Function
,则过程会返回 returntype
中指定的数据类型的默认值。 如果未指定 returntype
,则过程会返回 Nothing
,这是 Object
的默认值。
调用函数
可在表达式中,使用过程名称(后跟括在括号中的参数列表)调用 Function
过程。 仅当未提供任何参数时,才可以省略括号。 但始终包含括号时,代码更具可读性。
采用与调用任何库函数(如 Sqrt
、Cos
或 ChrW
)相同的方式来调用 Function
过程。
还可以使用 Call
关键字调用函数。 在这种情况下,会忽略返回值。 在大多数情况下不建议使用 Call
关键字。 有关详细信息,请参阅 Call 语句。
Visual Basic 有时会重新排列算术表达式,以提高内部效率。 出于此原因,当函数在相同表达式中更改变量的值时,不应在算术表达式中使用 Function
过程。
异步函数
异步功能使你可以调用异步函数而无需使用显式回调,也不需要跨多个函数或 Lambda 表达式来手动拆分代码。
如果用 Async 修饰符标记函数,则可以在该函数中使用 Await 运算符。 在控制到达 Async
方法中的 Await
表达式时,控制会返回到调用方,该函数中的进程会暂停,直到等待的任务完成为止。 任务完成后,可以在函数中恢复执行。
注意
Async
过程在遇到第一个尚未完成的 awaited 对象或到达 Async
过程末尾时(以先发生者为准),将返回到调用方。
Async
函数可以具有 Task<TResult> 或 Task 返回类型。 下面提供了返回类型为 Task<TResult> 的 Async
函数的示例。
Async
函数不能声明任何 ByRef 参数。
还可以使用 Async
修饰符标记 Sub 语句。 这主要用于无法返回值的事件处理程序。 无法等待 Async
Sub
过程,并且 Async
Sub
过程的调用方无法捕获 Sub
过程引发的异常。
有关 Async
方法的详细信息,请参阅使用 Async 和 Await 的异步编程、异步程序中的控制流和异步返回类型。
迭代器函数
迭代器函数对集合执行自定义迭代,如列表或数组。 迭代器函数使用 Yield 语句返回每个元素,每次返回一个。 到达 Yield 语句时,会记住当前在代码中的位置。 下次调用迭代器函数时,将从该位置重新开始执行。
通过使用 For Each…Next 语句从客户端代码调用迭代器。
迭代器函数的返回类型可以是 IEnumerable、IEnumerable<T>、IEnumerator 或 IEnumerator<T>。
有关更多信息,请参见 迭代器。
示例 1
以下示例使用 Function
语句来声明构成 Function
过程体的名称、参数和代码。 ParamArray
修饰符使函数能够接受可变数量的参数。
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
示例 2
下面的示例调用在前面的示例中声明的函数。
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
示例 3
在以下示例中,DelayAsync
是返回类型为 Task<TResult> 的 Async
Function
。 DelayAsync
具有返回整数的 Return
语句。 因此,DelayAsync
的函数声明需要具有返回类型 Task(Of Integer)
。 因为返回类型是 Task(Of Integer)
,DoSomethingAsync
过程中 Await
表达式的计算会生成整数。 此语句演示了这一点:Dim result As Integer = Await delayTask
。
startButton_Click
过程是 Async Sub
过程的一个示例。 因为 DoSomethingAsync
是 Async
函数,所以调用 DoSomethingAsync
的任务必须等待,如以下语句所示:Await DoSomethingAsync()
。 startButton_Click
Sub
过程必须使用 Async
修饰符进行定义,因为该过程具有 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