Sub 语句 (Visual Basic)Sub Statement (Visual Basic)

声明定义过程的名称、参数和代码 SubDeclares the name, parameters, and code that define a Sub procedure.

语法Syntax

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

组成部分Parts

  • attributelist

    可选。Optional. 请参阅特性列表See Attribute List.

  • Partial

    可选。Optional. 指示分部方法的定义。Indicates definition of a partial method. 请参阅分部方法See Partial Methods.

  • accessmodifier

    可选。Optional. 可以是以下其中一个值:Can be one of the following:

    请参阅Visual Basic 中的访问级别See Access levels in Visual Basic.

  • proceduremodifiers

    可选。Optional. 可以是以下其中一个值:Can be one of the following:

  • Shared

    可选。Optional. 请参阅共享See Shared.

  • Shadows

    可选。Optional. 请参阅阴影See Shadows.

  • Async

    可选。Optional. 请参阅AsyncSee Async.

  • name

    必需。Required. 过程的名称。Name of the procedure. 请参阅 Declared Element NamesSee Declared Element Names. 若要为类创建构造函数过程,请将过程的名称设置 SubNew 关键字。To create a constructor procedure for a class, set the name of a Sub procedure to the New keyword. 有关详细信息,请参阅对象生存期:如何创建和销毁对象For more information, see Object Lifetime: How Objects Are Created and Destroyed.

  • typeparamlist

    可选。Optional. 泛型过程的类型参数的列表。List of type parameters for a generic procedure. 请参阅类型列表See Type List.

  • parameterlist

    可选。Optional. 表示此过程参数的本地变量名称列表。List of local variable names representing the parameters of this procedure. 请参阅参数列表See Parameter List.

  • Implements

    可选。Optional. 指示此过程实现了一个或多个 Sub 过程,每个过程都在此过程的包含类或结构实现的接口中定义。Indicates that this procedure implements one or more Sub procedures, each one defined in an interface implemented by this procedure's containing class or structure. 请参阅Implements 语句See Implements Statement.

  • implementslist

    如果提供 Implements,则是必需的。Required if Implements is supplied. 所实现的 Sub 过程的列表。List of Sub procedures being implemented.

    implementedprocedure [ , implementedprocedure ... ]

    每个 implementedprocedure 都具有以下语法和部件:Each implementedprocedure has the following syntax and parts:

    interface.definedname

    组成部分Part 说明Description
    interface 必需。Required. 此过程的包含类或结构实现的接口的名称。Name of an interface implemented by this procedure's containing class or structure.
    definedname 必需。Required. interface 中用于定义过程的名称。Name by which the procedure is defined in interface.
  • Handles

    可选。Optional. 指示此过程可以处理一个或多个特定事件。Indicates that this procedure can handle one or more specific events. 请参阅句柄See Handles.

  • eventlist

    如果提供 Handles,则是必需的。Required if Handles is supplied. 此过程处理的事件列表。List of events this procedure handles.

    eventspecifier [ , eventspecifier ... ]

    每个 eventspecifier 都具有以下语法和部件:Each eventspecifier has the following syntax and parts:

    eventvariable.event

    组成部分Part 说明Description
    eventvariable 必需。Required. 用引发事件的类或结构的数据类型声明的对象变量。Object variable declared with the data type of the class or structure that raises the event.
    event 必需。Required. 此过程处理的事件的名称。Name of the event this procedure handles.
  • statements

    可选。Optional. 要在此过程中运行的语句块。Block of statements to run within this procedure.

  • End Sub

    终止此过程的定义。Terminates the definition of this procedure.

备注Remarks

所有可执行代码都必须在过程内。All executable code must be inside a procedure. Sub如果不想将值返回到调用代码,请使用过程。Use a Sub procedure when you don't want to return a value to the calling code. Function如果要返回值,请使用过程。Use a Function procedure when you want to return a value.

定义 Sub 过程Defining a Sub Procedure

只能 Sub 在模块级别定义过程。You can define a Sub procedure only at the module level. 因此,sub 过程的声明上下文必须是类、结构、模块或接口,不能是源文件、命名空间、过程或块。The declaration context for a sub procedure must, therefore, be a class, a structure, a module, or an interface and can't be a source file, a namespace, a procedure, or a block. 有关详细信息,请参阅声明上下文和默认访问级别For more information, see Declaration Contexts and Default Access Levels.

Sub过程默认为公共访问。Sub procedures default to public access. 您可以使用访问修饰符调整其访问级别。You can adjust their access levels by using the access modifiers.

如果过程使用 Implements 关键字,则包含类或结构必须具有 Implements 紧跟在其或语句后面的语句 Class StructureIf the procedure uses the Implements keyword, the containing class or structure must have an Implements statement that immediately follows its Class or Structure statement. Implements语句必须包括在中指定的每个接口 implementslistThe Implements statement must include each interface that's specified in implementslist. 但是,接口用于定义 Sub (在中)的名称不必 definedname 与此过程的名称匹配(在中为 name )。However, the name by which an interface defines the Sub (in definedname) doesn't have to match the name of this procedure (in name).

从 Sub 过程返回Returning from a Sub Procedure

Sub 过程返回到调用代码时,执行将继续执行调用它的语句之后的语句。When a Sub procedure returns to the calling code, execution continues with the statement after the statement that called it.

下面的示例演示如何从过程返回 SubThe following example shows a return from a Sub procedure.

Sub mySub(ByVal q As String)
    Return
End Sub

Exit SubReturn 语句导致直接从 Sub 过程退出。The Exit Sub and Return statements cause an immediate exit from a Sub procedure. 任意数量的 Exit SubReturn 语句可以出现在过程中的任何位置,并且可以混合使用 Exit SubReturn 语句。Any number of Exit Sub and Return statements can appear anywhere in the procedure, and you can mix Exit Sub and Return statements.

调用 Sub 过程Calling a Sub Procedure

Sub通过在语句中使用过程名称,然后将该名称跟在括号中的参数列表后面来调用过程。You call a Sub procedure by using the procedure name in a statement and then following that name with its argument list in parentheses. 仅当未提供任何参数时,才可以省略括号。You can omit the parentheses only if you don't supply any arguments. 但是,如果你始终包含括号,你的代码将更具可读性。However, your code is more readable if you always include the parentheses.

Sub过程和 Function 过程可以具有参数并执行一系列语句。A Sub procedure and a Function procedure can have parameters and perform a series of statements. Function 过程返回值,并且 Sub 过程不会。However, a Function procedure returns a value, and a Sub procedure doesn't. 因此,不能 Sub 在表达式中使用过程。Therefore, you can't use a Sub procedure in an expression.

您可以在 Call 调用过程时使用关键字 Sub ,但对于大多数用途,不建议使用该关键字。You can use the Call keyword when you call a Sub procedure, but that keyword isn't recommended for most uses. 有关详细信息,请参阅Call 语句For more information, see Call Statement.

Visual Basic 有时会重新排列算术表达式以提高内部效率。Visual Basic sometimes rearranges arithmetic expressions to increase internal efficiency. 出于此原因,如果参数列表包含调用其他过程的表达式,则不应假定将按特定顺序调用这些表达式。For that reason, if your argument list includes expressions that call other procedures, you shouldn't assume that those expressions will be called in a particular order.

Async Sub 过程Async Sub Procedures

通过使用异步功能,你可以调用异步函数而无需使用显式回调或在多个函数或 lambda 表达式中手动拆分你的代码。By using the Async feature, you can invoke asynchronous functions without using explicit callbacks or manually splitting your code across multiple functions or lambda expressions.

如果使用Async修饰符标记过程,则可以在过程中使用Await运算符。If you mark a procedure with the Async modifier, you can use the Await operator in the procedure. 当控件 Await 在过程中到达表达式时 Async ,控件将返回到调用方,并且在等待的任务完成之前,会挂起过程中的进度。When control reaches an Await expression in the Async procedure, control returns to the caller, and progress in the procedure is suspended until the awaited task completes. 任务完成后,可以在过程中继续执行。When the task is complete, execution can resume in the procedure.

备注

Async如果遇到了第一个尚未完成的对象或过程结束时 Async (以先发生者为准),则过程返回到调用方。An Async procedure returns to the caller when either the first awaited object that’s not yet complete is encountered or the end of the Async procedure is reached, whichever occurs first.

还可以使用修饰符标记函数语句 AsyncYou can also mark a Function Statement with the Async modifier. Async函数的返回类型可以是 Task<TResult>TaskAn Async function can have a return type of Task<TResult> or Task. 本主题后面的示例演示了 Async 返回类型为的函数 Task<TResult>An example later in this topic shows an Async function that has a return type of Task<TResult>.

Async``Sub过程主要用于事件处理程序,其中不能返回值。Async Sub procedures are primarily used for event handlers, where a value can't be returned. Async Sub 无法等待过程,并且过程的调用方 Async Sub 无法捕获该 Sub 过程引发的异常。An Async Sub procedure can't be awaited, and the caller of an Async Sub procedure can't catch exceptions that the Sub procedure throws.

Async过程不能声明任何ByRef参数。An Async procedure can't declare any ByRef parameters.

有关过程的详细信息 Async ,请参阅采用 Async 和 Await 的异步编程异步程序中的控制流异步返回类型For more information about Async procedures, see Asynchronous Programming with Async and Await, Control Flow in Async Programs, and Async Return Types.

示例Example

下面的示例使用 Sub 语句来定义构成过程正文的名称、参数和代码 SubThe following example uses the Sub statement to define the name, parameters, and code that form the body of a Sub procedure.

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

示例Example

在下面的示例中, DelayAsyncAsync Function 具有返回类型的 Task<TResult>In the following example, DelayAsync is an Async Function that has a return type of Task<TResult>. DelayAsync 具有返回整数的 Return 语句。DelayAsync has a Return statement that returns an integer. 因此,的函数声明 DelayAsync 必须具有返回类型 Task(Of Integer)Therefore, the function declaration of DelayAsync must have a return type of Task(Of Integer). 由于返回类型是 Task(Of Integer) ,中表达式的计算会 Await DoSomethingAsync 生成一个整数,如以下语句所示: Dim result As Integer = Await delayTaskBecause the return type is Task(Of Integer), the evaluation of the Await expression in DoSomethingAsync produces an integer, as the following statement shows: Dim result As Integer = Await delayTask.

startButton_Click 过程是过程的示例 Async SubThe startButton_Click procedure is an example of an Async Sub procedure. 由于 DoSomethingAsync 是一个 Async 函数,因此对的调用的任务 DoSomethingAsync 必须等待,如以下语句所示: Await DoSomethingAsync()Because DoSomethingAsync is an Async function, the task for the call to DoSomethingAsync must be awaited, as the following statement shows: Await DoSomethingAsync(). startButton_Click Sub 过程必须使用修饰符进行定义, Async 因为它具有 Await 表达式。The startButton_Click Sub procedure must be defined with the Async modifier because it has an Await expression.

' 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

另请参阅See also