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

    可选。 可以是以下值之一:

    请参阅 Access levels in Visual Basic

  • proceduremodifiers

    可选。 可以是以下值之一:

  • Shared

    可选。 请参阅 Shared

  • Shadows

    可选。 请参阅 Shadows

  • Async

    可选。 请参阅 Async

  • Iterator

    可选。 请参阅 Iterator

  • name

    必需。 过程的名称。 请参阅 Declared Element Names

  • typeparamlist

    可选。 泛型过程的类型参数列表。 请参阅类型列表

  • parameterlist

    可选。 表示此过程的参数的局部变量名称列表。 请参阅参数列表

  • returntype

    如果 Option StrictOn,则是必需的。 此过程返回的值的数据类型。

  • 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 关键字,则包含的类或结构必须还有一个紧跟在 ClassStructure 语句后的 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 FunctionReturn 语句将导致立即退出 Function 过程。 任意数量的 Exit FunctionReturn 语句可以出现在过程中的任何位置,并且你可以混合使用 Exit FunctionReturn 语句。

如果你在没有为 name 赋值的情况下使用 Exit Function,则过程会返回 returntype 中指定的数据类型的默认值。 如果未指定 returntype,则过程会返回 Nothing,这是 Object 的默认值。

调用函数

可在表达式中,使用过程名称(后跟括在括号中的参数列表)调用 Function 过程。 仅当未提供任何参数时,才可以省略括号。 但始终包含括号时,代码更具可读性。

采用与调用任何库函数(如 SqrtCosChrW)相同的方式来调用 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 语句。 这主要用于无法返回值的事件处理程序。 无法等待 AsyncSub 过程,并且 AsyncSub 过程的调用方无法捕获 Sub 过程引发的异常。

有关 Async 方法的详细信息,请参阅使用 Async 和 Await 的异步编程异步程序中的控制流异步返回类型

迭代器函数

迭代器函数对集合执行自定义迭代,如列表或数组。 迭代器函数使用 Yield 语句返回每个元素,每次返回一个。 到达 Yield 语句时,会记住当前在代码中的位置。 下次调用迭代器函数时,将从该位置重新开始执行。

通过使用 For Each…Next 语句从客户端代码调用迭代器。

迭代器函数的返回类型可以是 IEnumerableIEnumerable<T>IEnumeratorIEnumerator<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>AsyncFunctionDelayAsync 具有返回整数的 Return 语句。 因此,DelayAsync 的函数声明需要具有返回类型 Task(Of Integer)。 因为返回类型是 Task(Of Integer)DoSomethingAsync 过程中 Await 表达式的计算会生成整数。 此语句演示了这一点:Dim result As Integer = Await delayTask

startButton_Click 过程是 Async Sub 过程的一个示例。 因为 DoSomethingAsyncAsync 函数,所以调用 DoSomethingAsync 的任务必须等待,如以下语句所示:Await DoSomethingAsync()startButton_ClickSub 过程必须使用 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

另请参阅