Welcome

首页 / 软件开发 / VB.NET / Visual Basic 9.0概述

Visual Basic 9.0概述2008-04-23Erik Meijer简介

Visual Basic 一直以生成实用的、面向数据的业务线应用程序为中心。尽管迁移到 .NET 为应用程序开发人员带来了统一的框架和托管平台,但是下一版本的 Visual Basic 包括一组对开发人员构建面向数据的应用程序时的工作效率影响深远的功能。这些语言扩展引入了适用于所有数据源的通用查询工具,不管是关系对象图、分层对象图还是 XML 文档。

本文档将简略介绍这些新增功能。

Visual Basic 9.0 入门要查看这些语言功能的实际作用,让我们首先看一个真实的示例 - CIA World Factbook 数据库。该数据库包含有关世界各国的各种地理、经济、社会和政治信息。为了演示示例,我们从每个国家/地区的名称及其首都/首府、总面积和总人口的架构开始。通过使用以下类(为简便起见,使用伪代码),在 Visual Basic 9.0 中表示此架构:

Class Country
Public Property Name As String
Public Property Area As Long
Public Property Population As Integer
End Class

下面是一个将用作运行示例的国家/地区数据库的小子集:

Dim countries = {
New Country With { .Name = "Palau", .Area = 458, .Population = 16952 }, _
New Country With { .Name = "Monaco", .Area = 1.9, .Population = 31719 }, _
New Country With { .Name = "Belize", .Area = 22960, .Population = 219296 }, _
New Country With { .Name = "Madagascar", .Area = 587040, .Population =
13670507}}

有了此列表,可以使用以下查询表达式来查询其人口少于一百万的所有国家/地区:

Dim smallCountries = From country In countries _
Where country.Population < 1000000 _
Select country
For Each country In SmallCountries
Console.WriteLine(country.Name)
Next

由于只有马达加斯加的居住人口超过一百万,因此在编译和运行后,上述程序将打印出下列国家/地区名称:

Palau
Monaco
Belize

让我们检查一下该程序,了解使得编写此程序如此简单的 Visual Basic 9.0 功能。首先,表示 Countries 的每个表达式的声明都使用新增的“对象初始值设定项”语法 New Country With {..., .Area = 458, ...},通过类似于现在 With 语句的、基于表达式的简明语法创建复杂的对象实例。

该声明还说明了“隐式类型的局部变量”声明,其中编译器通过声明右侧的初始值设定项表达式来推断局部变量 Countries 的类型。上述声明完全等效于 Country() 类型的显式类型局部变量声明。

Dim countries As Country() = {...}

重申一下,这仍然是强类型声明;编译器已自动推断局部声明右侧的类型,程序员无需在程序中手动输入该类型。

使用 SQL 样式的查询表达式初始化局部变量声明 SmallCountries,筛选出居住人口少于一百万的所有国家/地区。查询表达式与 SQL 类似是有意的,这样已经了解 SQL 的程序员就可以更快地了解 Visual Basic 查询语法。

Dim smallCountries = From country In Countries _
Where country.Population < 1000000 _
Select country

请注意,此代码示例表示另一个隐式类型的应用程序:编译器根据查询表达式的结果类型,将 SmallCountries 的类型推断为 IEnumerable(Of Country)。编译器将查询表达式本身转换为对启用 LINQ 的 API(它为实现 IEnumerable(Of T) 的所有类型实现查询运算符)的调用。在这种情况下,转换就像下面一样简单:

Dim smallCountries As IEnumerable(Of Country) = _
Countries.Where(Function(country) country.Population < 1000000). _
Select(Function(country) country)

扩展语法取决于“lambda 表达式”,后者表示返回表达式结果的内联函数。lambda 表达式被转换为委托并传递到扩展函数 Where,该函数在标准查询运算符库中被定义为 IEnumerable(Of T) 接口的扩展。

我们已了解 Visual Basic 9.0 的几项新增功能,接下来让我们深入了解更多内容。

隐式类型的局部变量在隐式类型的局部变量声明中,局部变量的类型是通过局部声明语句右侧的初始值设定项表达式推断的。例如,编译器推断以下所有变量声明的类型:

Dim population = 31719
Dim name = "Belize"
Dim area = 1.9
Dim country = New Country With { .Name = "Palau", ...}

因此,它们完全等效于以下显式类型声明:

Dim population As Integer = 31719
Dim name As String = "Belize"
Dim area As Float = 1.9
Dim country As Country = New Country With { .Name = "Palau", ...}

由于局部变量声明的类型是通过新增的 Option Infer On(新项目的默认值)推断的,因此不管 Option Strict 的设置如何,对此类变量的访问始终是早期绑定的。程序员必须在 Visual Basic 9.0 中显式指定后期绑定,方法是将变量显式声明为 Object 类型,如下所示:

Dim country As Object = New Country With { .Name = "Palau", ... }

推断类型可防止意外使用后期绑定,更重要的是,它允许为新数据类型(如 XML)绑定强大扩展,如下所示。

For...Next 或 For Each...Next 语句中的循环控制变量也可以是隐式类型的变量。指定循环控制变量时(如 For I = 0 To SmallCountries.Count 或 For Each country In smallCountries 中所示),标识符定义一个新的隐式类型局部变量,其类型通过初始值设定项或集合表达式推断且作用于整个循环。通过应用此类型推断,可以重新编写打印所有小国家/地区的循环,如下所示:

For Each country In smallCountries
Console.WriteLine(country.Name)
Next

country 的类型被推断为 Country,即 SmallCountries 的元素类型。

对象和数组初始值设定项在 Visual Basic 中,With 语句简化了对一个聚合值的多个成员的访问,而无须多次指定目标表达式。在 With 语句块内,对以句点开头的成员访问表达式进行计算,好像句点前面有 With 语句的目标表达式。例如,以下语句初始化新的 Country 实例,随后将其字段初始化为所需的值:

Dim palau As New Country()
With palau
.Name = "Palau"
.Area = 458
.Population = 16952
End With

Visual Basic 9.0 中新增的“对象初始值设定项”是基于表达式的 With 语句,用于简明地创建复杂的对象实例。使用对象初始值设定项,可以将上述两条语句捕获到单个(隐式类型的)局部声明中,如下所示:

Dim palau = New Country With { _
.Name = "Palau", _
.Area = 458, _
.Population = 16952 _
}

表达式中此样式的对象初始化对查询是很重要的。通常,查询类似于由等号右侧的 Select 子句初始化的对象声明。由于 Select 子句返回表达式,因此必须能够用单个表达式初始化整个对象。

正如我们所看到的那样,对象初始值设定项还便于为复杂对象创建集合。通过使用“数组初始值设定项”表达式,可以初始化数组和推断元素类型。例如,假定将城市的声明作为类,

Class City
Public Property Name As String
Public Property Country As String
Public Property Longitude As Long
Public Property Latitude As Long
End Class

则可以为示例国家/地区创建首都/首府数组,如下所示:

Dim Capitals = { _
New City With { _
.Name = "Antanarivo", _
.Country = "Madagascar", _
.Longitude = 47.4, _
.Latitude = -18.6 }, _
New City With { _
.Name = "Belmopan", _
.Country = "Belize", _
.Longitude = -88.5, _
.Latitude = 17.1 }, _
New City With { _
.Name = "Monaco", _
.Country = "Monaco", _
.Longitude = 7.2, _
.Latitude = 43.7 }, _
New City With { _
.Country = "Palau",
.Name = "Koror", _
.Longitude = 135, _
.Latitude = 8 } _
}