语句 (Visual Basic)

Visual Basic 中的语句是一条完整指令。 它可以包含关键字、运算符、变量、常量和表达式。 每个语句属于以下类别之一:

  • 声明语句,用于为变量、常量或过程命名,还可以指定数据类型。

  • 可执行语句,用于启动操作。 这些语句可以调用方法或函数,可以循环访问代码块或创建其分支。 可执行语句包括赋值语句,即将值或表达式赋给变量或常量的语句。

本主题将介绍每个类别。 此外,本主题还将介绍如何在一行中组合多个语句,以及如何在多行中续写一条语句。

声明语句

使用声明语句来命名和定义过程、变量、属性、数组与常量。 声明编程元素时,还可以定义其数据类型、访问级别和范围。 有关详细信息,请参阅声明的元素特征

以下示例包含三个声明。

Public Sub ApplyFormat()
    Const limit As Integer = 33
    Dim thisWidget As New widget
    ' Insert code to implement the procedure.
End Sub

第一个声明是 Sub 语句。 该语句连同其匹配的 End Sub 语句声明了一个名为 applyFormat 的过程。 它还指定 applyFormatPublic,即,任何可引用该过程的代码都可以调用该过程。

第二个声明是 Const 语句,它声明常量 limit,并指定 Integer 数据类型和值 33。

第三个声明是 Dim 语句,它声明变量 thisWidget。 数据类型是特定的对象,即从 Widget 类创建的对象。 可将变量声明为任何基本数据类型,或者在使用的应用程序中公开的任何对象类型。

初始值

在运行包含声明语句的代码时,Visual Basic 将预留声明的元素所需的内存。 如果元素包含值,则 Visual Basic 会将其初始化为其数据类型的默认值。 有关详细信息,请参阅 Dim 语句中的“行为”。

可将初始值作为变量声明的一部分赋给该变量,如以下示例所示。

Dim m As Integer = 45
' The preceding declaration creates m and assigns the value 45 to it.

如果变量是对象变量,则你可以在声明该变量时使用 New Operator 关键字显式创建其类的实例,如以下示例所示。

Dim f As New FileInfo("filename")

请注意,在执行到达其声明语句之前,在声明语句中指定的初始值不会赋给变量。 在此之前,该变量包含其数据类型的默认值。

可执行语句

一条可执行语句执行一个操作。 它可以调用过程、分支到代码中的另一个位置、循环访问多个语句或计算表达式。 赋值语句是可执行语句的一种特殊情况。

以下示例使用 If...Then...Else 控制结构根据变量的值运行不同的代码块。 在每个代码块中,For...Next 循环运行指定的次数。

Public Sub StartWidget(ByVal aWidget As widget,
    ByVal clockwise As Boolean, ByVal revolutions As Integer)
    Dim counter As Integer
    If clockwise = True Then
        For counter = 1 To revolutions
            aWidget.SpinClockwise()
        Next counter
    Else
        For counter = 1 To revolutions
            aWidget.SpinCounterClockwise()
        Next counter
    End If
End Sub

以上示例中的 If 语句检查参数 clockwise 的值。 如果值为 True,该语句将调用 aWidgetspinClockwise 方法。 如果值为 False,该语句将调用 aWidgetspinCounterClockwise 方法。 If...Then...Else 控制结构以 End If 结尾。

每个块中的 For...Next 循环调用相应的方法,调用次数等于 revolutions 参数的值。

赋值语句

赋值语句执行赋值操作,这些操作包括获取赋值运算符 (=) 右侧的值并将其存储在左侧的元素中,如以下示例所示。

v = 42

在以上示例中,赋值语句将文本值 42 存储在变量 v 中。

符合条件的编程元素

赋值运算符左侧的编程元素必须能够接受和存储某个值。 这意味着,它必须为非 ReadOnly 的变量或属性,或者必须是数组元素。 在赋值语句的上下文中,此类元素有时称为 lvalue(表示“左值”)。

赋值运算符右侧的值由表达式生成,该表达式可以由文本、常量、变量、属性、数组元素、其他表达式或函数调用的任意组合组成。 下面的示例对此进行了演示。

x = y + z + FindResult(3)

以上示例将变量 y 中包含的值与变量 z 中包含的值相加,然后与 findResult 函数调用返回的值相加。 然后将此表达式的总计值存储在变量 x 中。

赋值语句中的数据类型

除了数值以外,赋值运算符还可以赋 String 值,如以下示例所示。

Dim a, b As String
a = "String variable assignment"
b = "Con" & "cat" & "enation"
' The preceding statement assigns the value "Concatenation" to b.

你也可以使用 Boolean 文本或 Boolean 表达式赋 Boolean 值,如以下示例所示。

Dim r, s, t As Boolean
r = True
s = 45 > 1003
t = 45 > 1003 Or 45 > 17
' The preceding statements assign False to s and True to t.

同样,可将适当的值赋给 CharDateObject 数据类型的编程元素。 还可将某个对象实例赋给声明为从中创建了该实例的类的元素。

复合赋值语句

复合赋值语句首先对表达式执行操作,然后将该表达式赋给编程元素。 以下示例演示了其中一个运算符 +=,它按照右侧表达式的值来递增运算符左侧的变量值。

n += 1

以上示例将 n 的值加 1,然后将此新值存储在 n 中。 它是以下语句的简写形式:

n = n + 1

使用这种类型的运算符可以执行各种复合赋值操作。 有关这些运算符的列表及其详细信息,请参阅赋值运算符

串联赋值运算符 (&=) 可用于将字符串添加到现有字符串的末尾,如以下示例所示。

Dim q As String = "Sample "
q &= "String"
' q now contains "Sample String".

赋值语句中的类型转换

赋给变量、属性或数组元素的值必须是适合该目标元素的数据类型。 一般情况下,应该尝试生成与目标元素数据类型相同的值。 但是,某些类型可以在赋值期间转换为其他类型。

有关在数据类型之间进行转换的信息,请参阅 Visual Basic 中的类型转换。 简而言之,Visual Basic 会自动将给定类型的值转换为该类型可扩大到的任何其他类型。 扩大转换是在运行时始终成功且不会丢失任何数据的一种转换。 例如,Visual Basic 在适当的情况下会将 Integer 值转换为 Double,因为 Integer 可扩大至 Double。 有关详细信息,请参阅 Widening and Narrowing Conversions

收缩转换(不扩大的转换)存在运行时失败或数据丢失的风险。 可以使用类型转换函数显式执行收缩转换,也可通过设置 Option Strict Off 来指示编译器隐式执行所有转换。 有关详细信息,请参阅隐式和显式转换

将多个语句放在一行中

可以在一行中包含多个语句并用冒号 (:) 字符分隔。 下面的示例对此进行了演示。

Dim sampleString As String = "Hello World" : MsgBox(sampleString)

这种语法形式虽然偶尔可以带来方便,但会使代码变得难以阅读和维护。 因此,建议将一条语句保留在一行中。

在多行中续写一条语句

通常适合在一行中编写一条语句,但如果该语句太长,可以使用续行序列将其延续到下一行,该序列包括一个空格,后接下划线字符 (_),再后接回车符。 在以下示例中,MsgBox 可执行语句延续了两行。

Public Sub DemoBox()
    Dim nameVar As String
    nameVar = "John"
    MsgBox("Hello " & nameVar _
        & ". How are you?")
End Sub

隐式续行

在许多情况下,可以在不使用下划线字符 (_) 的情况下,在下一个连续行中续写语句。 以下语法元素在下一个代码行中隐式续写语句。

  • 在逗号 (,) 后面。 例如:

    Public Function GetUsername(ByVal username As String,
                                ByVal delimiter As Char,
                                ByVal position As Integer) As String
    
        Return username.Split(delimiter)(position)
    End Function
    
  • 在左括号 (() 后面或右括号 ()) 前面。 例如:

    Dim username = GetUsername(
        Security.Principal.WindowsIdentity.GetCurrent().Name,
        CChar("\"),
        1
      )
    
  • 在左大括号 ({) 后面或右大括号 (}) 前面。 例如:

    Dim customer = New Customer With {
      .Name = "Terry Adams",
      .Company = "Adventure Works",
      .Email = "terry@www.adventure-works.com"
    }
    

    有关详细信息,请参阅对象初始值设定项:命名类型和匿名类型集合初始值设定项

  • 在 XML 文本中的左嵌入式表达式 (<%=) 后面或右嵌入式表达式 (%>) 前面。 例如:

    Dim customerXml = <Customer>
                          <Name>
                              <%=
                                  customer.Name
                              %>
                          </Name>
                          <Email>
                              <%=
                                  customer.Email
                              %>
                          </Email>
                      </Customer>
    

    有关详细信息,请参阅 XML 中的嵌入式表达式

  • 在串联运算符 (&) 后面。 例如:

    cmd.CommandText = 
        "SELECT * FROM Titles JOIN Publishers " &
        "ON Publishers.PubId = Titles.PubID " &
        "WHERE Publishers.State = 'CA'"
    

    有关详细信息,请参阅按功能列出的运算符

  • 在赋值运算符(=&=:=+=-=*=/=\=^=<<=>>=)后面。 例如:

    Dim fileStream =
      My.Computer.FileSystem.
        OpenTextFileReader(filePath)
    

    有关详细信息,请参阅按功能列出的运算符

  • 在表达式中的二元运算符(+-/*Mod<><><=>=^>><<AndAndAlsoOrOrElseLikeXor)后面。 例如:

    Dim memoryInUse =
      My.Computer.Info.TotalPhysicalMemory +
      My.Computer.Info.TotalVirtualMemory -
      My.Computer.Info.AvailablePhysicalMemory -
      My.Computer.Info.AvailableVirtualMemory
    

    有关详细信息,请参阅按功能列出的运算符

  • IsIsNot 运算符后面。 例如:

    If TypeOf inStream Is 
      IO.FileStream AndAlso
      inStream IsNot
      Nothing Then
    
        ReadFile(inStream)
    
    End If
    

    有关详细信息,请参阅按功能列出的运算符

  • 在成员限定符 (.) 后面和成员名称前面。 例如:

    Dim fileStream =
      My.Computer.FileSystem.
        OpenTextFileReader(filePath)
    

    但是,在使用 With 语句时或者在类型的初始化列表中提供值时,必须在成员限定符后面包含一个续行符 (_)。 在使用 = 语句或对象初始化列表时,请考虑在赋值运算符(例如 With)后面换行。 例如:

    ' Not allowed:
    ' Dim aType = New With { .
    '    PropertyName = "Value"
    
    ' Allowed:
    Dim aType = New With {.PropertyName =
        "Value"}
    
    
    
    Dim log As New EventLog()
    
    ' Not allowed:
    ' With log
    '    .
    '      Source = "Application"
    ' End With
    
    ' Allowed:
    With log
        .Source =
          "Application"
    End With
    

    有关详细信息,请参阅 With...End With 语句对象初始值设定项:命名类型和匿名类型

  • 在 XML 轴属性限定符(..@...)后面。 但是,如果在使用 With 关键字时指定成员限定符,则必须包含一个续行符 (_)。 例如:

    Dim customerName = customerXml.
      <Name>.Value
    
    Dim customerEmail = customerXml...
      <Email>.Value
    

    有关详细信息,请参阅 XML 轴属性

  • 指定属性时在小于号 (<) 后面或大于号 (>) 前面续行。 也可以在指定属性时在大于号 (>) 后面续行。 但是,在指定程序集级或模块级属性时,必须包含一个续行符 (_)。 例如:

    <
    Serializable()
    >
    Public Class Customer
        Public Property Name As String
        Public Property Company As String
        Public Property Email As String
    End Class
    

    有关详细信息,请参阅属性概述

  • 在查询运算符(AggregateDistinctFromGroup ByGroup JoinJoinLetOrder BySelectSkipSkip WhileTakeTake WhileWhereInIntoOnAscendingDescending)的前面和后面。 不能在由多个关键字(Order ByGroup JoinTake WhileSkip While)构成的查询运算符的关键字之间换行。 例如:

    Dim vsProcesses = From proc In
                        Process.GetProcesses
                      Where proc.MainWindowTitle.Contains("Visual Studio")
                      Select proc.ProcessName, proc.Id,
                             proc.MainWindowTitle
    

    有关详细信息,请参阅查询

  • For Each 语句中的 In 关键字后面。 例如:

    For Each p In
      vsProcesses
    
        Console.WriteLine("{0}" & vbTab & "{1}" & vbTab & "{2}",
          p.ProcessName,
          p.Id,
          p.MainWindowTitle)
    Next
    

    有关详细信息,请参阅 For Each...Next 语句

  • 在集合初始值设定项中的 From 关键字后面。 例如:

    Dim days = New List(Of String) From
      {
       "Mo", "Tu", "We", "Th", "F", "Sa", "Su"
      }
    

    有关详细信息,请参阅集合初始值设定项

添加注释

即使对于编写源代码的程序员而言,这些代码也并非始终一目了然。 因此,为了帮助阐释其代码,大多数程序员都会体贴地使用嵌入式注释。 代码中的注释可为今后阅读或使用这些代码的任何人解释某个过程或特定指令。 Visual Basic 在编译期间会忽略注释,注释不会影响编译的代码。

注释行以撇号 (') 或 REM 开头,后接一个空格。 可以在代码中的任何位置添加注释,但不能在字符串中添加。 若要为某条语句追加注释,请在该语句后面插入撇号或 REM,然后添加注释。 也可以独行添加注释。 以下示例演示了这些可能的做法。

' This is a comment on a separate code line.
REM This is another comment on a separate code line.
x += a(i) * b(i) ' Add this amount to total.
MsgBox(statusMessage) REM Inform operator of status.

检查编译错误

如果在键入一个代码行后,该行显示蓝色的波浪下划线(也可能附带出现错误消息),则表示语句中存在语法错误。 必须找出该语句的问题所在(通过查看任务列表,或者将鼠标指针悬停在错误上并阅读错误消息)并予以更正。 只有在修复代码中的所有语法错误之后,程序才能正常编译。

术语 定义
赋值运算符 提供介绍赋值运算符(例如 =*=&=)的语言参考页的链接。
运算符和表达式 介绍如何将元素与运算符相结合以生成新值。
如何:在代码中拆分和合并语句 介绍如何将一条语句拆分到多行,以及如何将多条语句放在同一行中。
如何:标记语句 显示如何标记代码行。