Sub 语句 (Visual Basic)

声明定义 Sub 过程的名称、参数和代码。

语法

[ <attributelist> ] [ Partial ] [ accessmodifier ] [ proceduremodifiers ] [ Shared ] [ Shadows ] [ Async ]
Sub name [ (Of typeparamlist) ] [ (parameterlist) ] [ Implements implementslist | Handles eventlist ]
    [ statements ]
    [ Exit Sub ]
    [ statements ]
End Sub

组成部分

  • attributelist

    可选。 请参阅特性列表

  • Partial

    可选。 表示分部方法的定义。 请参阅分部方法

  • accessmodifier

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

    请参阅 Access levels in Visual Basic

  • proceduremodifiers

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

  • Shared

    可选。 请参阅 Shared

  • Shadows

    可选。 请参阅 Shadows

  • Async

    可选。 请参阅 Async

  • name

    必需。 过程的名称。 请参阅 Declared Element Names。 若要为类创建构造函数过程,请将 Sub 过程的名称设置为 New 关键字。 有关详细信息,请参阅对象生存期:如何创建和销毁对象

  • typeparamlist

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

  • parameterlist

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

  • Implements

    可选。 表示该过程实现了一个或多个 Sub 过程,每个过程都在由该过程的包含类或结构实现的接口中定义。 请参阅 Implements 语句

  • implementslist

    如果提供 Implements,则是必需的。 所实现的 Sub 过程的列表。

    implementedprocedure [ , implementedprocedure ... ]

    每个 implementedprocedure 都具有以下语法和部件:

    interface.definedname

    组成部分 说明
    interface 必需。 此过程的包含类或结构所实现的接口的名称。
    definedname 必需。 在 interface 中用于定义过程的名称。
  • Handles

    可选。 表示此过程可以处理一个或多个特定事件。 请参阅句柄

  • eventlist

    如果提供 Handles,则是必需的。 此过程处理的事件列表。

    eventspecifier [ , eventspecifier ... ]

    每个 eventspecifier 都具有以下语法和部件:

    eventvariable.event

    组成部分 说明
    eventvariable 必需。 使用引发事件的类或结构的数据类型声明的对象变量。
    event 必需。 此过程处理的事件的名称。
  • statements

    可选。 在此过程中运行的语句块。

  • End Sub

    终止此过程的定义。

注解

所有可执行代码都必须位于某一过程中。 不想将值返回给调用代码时,使用 Sub 过程。 想要返回值时,使用 Function 过程。

定义 Sub 过程

你只能在模块级别定义 Sub 过程。 因此,Sub 过程的声明上下文必须是类、结构、模块或接口,不能是源文件、命名空间、过程或块。 有关详细信息,请参阅声明上下文和默认访问级别

Sub 过程默认为公共访问。 可以使用访问修饰符调整其访问级别。

如果此过程使用 Implements 关键字,则包含的类或结构必须有一个 Implements 语句,并且紧跟在 ClassStructure 语句后面。 Implements 语句必须包括在 implementslist 中指定的每个接口。 但是,接口定义 Sub(在 definedname 中)的名称不必与该过程的名称(在 name 中)相同。

从 Sub 过程中返回

Sub 过程返回到调用代码时,将继续执行调用它的语句之后的语句。

以下示例显示了 Sub 过程的返回值。

Sub mySub(ByVal q As String)
    Return
End Sub

Exit SubReturn 语句将导致立即退出 Sub 过程。 任意数量的 Exit SubReturn 语句可以出现在过程中的任何位置,并且你可以混合使用 Exit SubReturn 语句。

调用 Sub 过程

可以通过在语句中使用过程名称并在该名称后面加上其以括号括起来的参数列表来调用 Sub 过程。 仅在未提供任何参数时,才可以省略括号。 但始终包含括号时,代码更具可读性。

Sub 过程和 Function 过程可以具有参数并执行一系列语句。 但 Function 过程会返回一个值,而 Sub 过程不会。 因此,你不能在表达式中使用 Sub 过程。

可以在调用 Sub 过程时使用 Call 关键字,但大多数情况下不建议使用该关键字。 有关详细信息,请参阅 Call 语句

Visual Basic 有时会重新排列算术表达式,以提高内部效率。 因此,如果参数列表包含调用其他过程的表达式,则不应假定将以特定顺序调用这些表达式。

Async Sub 过程

通过使用 Async 功能,你可以调用异步函数而无需使用显式回调,也不需要跨多个函数或 Lambda 表达式来手动拆分代码。

如果用 Async 修饰符标记过程,则可以在该过程中使用 Await 运算符。 在控制到达 Async 过程的 Await 表达式时,控制将返回到调用方,该过程中的进程将挂起,直到等待的任务完成为止。 任务完成后,可以在过程中恢复执行。

注意

Async 过程在遇到第一个尚未完成的 awaited 对象或到达 Async 过程的末尾时(以先发生者为准),将返回到调用方。

你还可以使用 Async 修饰符标记 Function 语句Async 函数可以具有 Task<TResult>Task 返回类型。 本主题后面的示例显示了返回类型为 Task<TResult>Async 函数。

AsyncSub 过程主要用于无法返回值的事件处理程序。 无法等待 AsyncSub 过程,并且 AsyncSub 过程的调用方无法捕获 Sub 过程引发的异常。

Async 过程无法声明任何 ByRef 参数。

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

示例 1

以下示例使用 Sub 语句来定义构成 Sub 过程主体的名称、参数和代码。

Sub ComputeArea(ByVal length As Double, ByVal width As Double)
    ' Declare local variable.
    Dim area As Double
    If length = 0 Or width = 0 Then
        ' If either argument = 0 then exit Sub immediately.
        Exit Sub
    End If
    ' Calculate area of rectangle.
    area = length * width
    ' Print area to Immediate window.
    Debug.WriteLine(area)
End Sub

示例 2

在以下示例中,DelayAsync 是返回类型为 Task<TResult>AsyncFunctionDelayAsync 具有返回整数的 Return 语句。 因此,DelayAsync 的函数声明必须具有返回类型 Task(Of Integer)。 因为返回类型是 Task(Of Integer)DoSomethingAsyncAwait 表达式的计算将如以下 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

请参阅