Visual Basic 10 概述
Visual Studio 2010 和 .NET Framework 4.0 专题的一部分
周融,2008 年 10 月
概述
Microsoft 今年 10 月宣布正式命名下一代开发平台和工具为 Microsoft .NET Framework 4.0 以及 Visual Studio 2010。Visual Studio 2010 先前代号 dev10,包含 Microsoft 最新的开发平台创新和扩展。本文通过 2008 年 10 月 27 号发布的 Visual Studio 2010 CTP 版本向大家完整介绍了 Visual Basic 10(代号 VBX)在该平台上的新增功能。
在本文中的内容
· 数组初始值设定项
· 集合初始值设定项
· 内联 Lambda 表达式
· 自动实现属性
· 泛化
· No-PIA 部署
· 与 Python 的集成
· 并行计算扩展
数组初始值设定项(Array Literals)
Visual Basic 9.0 在对一个数组类型的变量进行初始化赋值时,可以通过隐式类型本地变量(Type Inference)由编译器推断该数组是什么类型。例如:
Dim strings = New String() { “A”, “B”, “C” }
Dim integers() = { 1, 2, 3, 4, 5 }
Visual Basic 10 增强了这一功能,在现在的版本中,我们不仅可以利用 Dim 语句声明隐式类型变量,而且可以在接受参数的函数调用中使用。例如,在一个接受 String 数组类型的 SearchPath 函数调用,就可以使用如下形式。
Dim results() = SearchPath( { “C:/”, “D:/”, “E:/” })
集合初始值设定项(Collection Initializer)
集合初始值设定项在 C# 3.0 中已经被引入,例如,我们现在需要对一个 List<string> 的对象增加三个 string,我们需要这样调用。
Dim list = New List(Of String)
list.Add(“string1”)
list.Add(“string2”)
list.Add(“string3”)
但在 Visual Basic 10 中,也可以和 C# 一样直接初始化了。例如上面的代码可以简写为如下代码。
Dim list = New List(Of String) From { “string1”, “string2”, “string3” }
这里的 From 关键字表明了该初始值从后面的集合中获得,这样的语法等同于前面所描述的利用 List.Add() 方法添加数据,不同的是 CLR 为我们完成了三次 Add() 方法的调用。
结合上面提到的两项创新,我们可以大大简化初始化变量的语法。例如。
Dim students = List(Of Student) From { _
New Student With { .Name := “Mark”, .Age := 24, .PhoneNumbers := { “123-XXX-XXXX”, “XXX-XXX-XXXX” } },
New Student With { .Name := “Evan”, .Age := 22, .PhoneNumbers := { } }
}
Public Class Student
Public Name As String
Public Age As Integer
Public PhoneNumbers As List(Of String)
End Class
内联 Lambda 表达式(Inline Lambda Expressions)
Visual Basic 9 引入了 Lambda 表达式,但由于 Visual Basic 的行结束符为回车,导致如果我们需要在 Lambda 函数体中执行多项操作时会很麻烦,C# 可以用括号将语句括起来形成语句块来解决这个问题,但 Visual Basic 就只能利用冒号将多个语句分开。
Visual Basic 10 提供了新的内联 Lambda 表达式支持,使得这一类问题可以顺利解决。如下面代码所示。
Dim t = New Thread(Sub()
myWorkingThread.Sleep(200)
myBackgroundThread.Suspend()
End Sub)
或者这样。
Dim f As New Func(Of Integer, Integer)
f = Function(x As Integer) As Integer
If x < 2 Then
Return 1
Else
Return f(x – 1) + f(x - 2)
End Function
Console.WriteLine(“10th element of Fibonacci is: {0}”, f(10))
自动实现属性(Auto Implemented Properties)
自动实现属性和 C# 中的相同概念是完全一致的。某些情况下,我们对属性的用途都是对私有字段的封装,那么在这种情况下,Get 和 Set 函数就可以省略。这种场景京城应用在 XML 序列化和数据集的 OR 模型中。
下面的代码演示了 Visual Basic 10 中的自动实现属性的用法。
Public Class Student
Public Property Name As String = String.Empty
Public Property Age As Integer = -1
Public Property PhoneNumbers As List(Of String) = New List(Of String)
End Class
泛化(Variance)
泛化的概念涉及到在泛型类型参数中的运行时转化。我们举一个例子,如果我们需要实现一个 RSS 源的订阅系统,我们的设计中可能包含一个 RssFeed(Of RssFeedItem) 的类,由于各个提供商的 RssItem 定义不同,则会导致有很多 RssItem 的继承类,如应用在 Windows Live Spaces 中的 WindowsLiveRssFeedItem 就继承自 RssItem 类,从而会产生 WindowsLiveRssFeed 的 RSS 源定义类。如果我们需要批量处理这些订阅的 RSS 源(也就是 RSSFeed 的继承类),则我们在编写汉书实现时,应使用基类型作为入口参数的类型。如。
Sub ProcessFeeds(ByVal feeds As RssFeed(Of RssFeedItem))
…
End Sub
如果我们这样传递一个参数给上述函数,编译器会怎样呢?
Dim rss = New RssFeed(Of WindowsLiveRssFeedItem)
ProcessFeeds(rss)
大家可能认为完全可以编译通过,没问题。但奇怪的事情发生了,编译器报告:无法将类型从 RssFeed(Of WindowsLiveRssFeedItem) 转换为 RssFeed(Of RssFeedItem)。
这是很显然的,泛型类型是强类型,泛型参数不同的两个泛型类的类型是不一样的,这时。我们必须在设计时利用 Cast 语句在运行时期间动态转换WindowsLiveRssFeedItem 为 RssFeedItem,这回引起性能问题和不必要的开销。
Visual Basic 10 通过将该泛型参数泛化来解决这个问题。在声明泛型类型时,通过在泛型参数前增加 Out 修饰就可以了。例如。
Class RssFeed(Of Out RssFeedItem)
…
End Class
则以上的代码就能正常工作。C# 4.0 同样增加了这个语法。我们还了解到,IEnumerable<T> 在默认情况下已经将泛型参数 T 修饰成了 Out。
这个功能如何工作的?Visual Basic Team 的一个 Dev 并没有透露,我们期待更加合理的解释。
No-PIA 部署(No PIA Deployment)
我们在编写基于 Microsoft Office 的应用程序时,往往需要部署一堆 VSTO 的 Runtime 程序集,但有时候我们编写一些应用程序时,仅仅调用了这些 Interop 程序集中很少的功能。例如仅仅保存或打开了一个 Excel 表格等,如果每次部署这样的应用程序都需要分发整个 PIA(Primary Interop Assemblies)的话就显得多此一举。在新的 Visual Basic 中,可以将一个 PIA 程序集的属性设置为 Embedded 来讲其用到的对象引用内嵌到您自己的程序集中,这样就避免了分发整个 VSTO Runtime 的臃肿部署方式。
与 Python 的集成
Visual Basic 10 提供了一个 Python 的适配器,可以动态的启动一个 Python 运行时,并通过对象来与 Python 运行时通讯完成共同协作。例如,您可以动态的启动一个 Python 解释器,并在该实例下声明一个 Python 的 string 类型变量,然后通过 .NET Framework 的 Console.Write() 方法将其输出。
Python 集成功能在目前的 CTP 版本并不可用。预计在 Visual Studio 2010 Beta 1 才真正提供这些特性支持。
并行计算扩展(Parallel Computing Extensions)
并行计算组已经准备好讲其并行计算扩展引入到 .NET Framework 4.0。并行计算针对多核处理器的计算机系统进行特别优化,从而充分利用 CPU 时间片并大大提供工作效率。目前,并行计算的 CTP 版本已经在 Microsoft 下载中心提供,大家有兴趣可以下载后试用。
并行计算扩展扩展了一个扩展方法 AsParallel(),增加类 Parallel 和 Future,并提供了一个任务管理器,专门用来对任务进行分配、管理和执行。并行计算扩展还提供了 PLINQ 语法,用来方便的将现有代码并行化。
下面代码一段适用 PLINQ 的代码。
Dim threads = GetWorkingThreads()
Parallel.ForAll(Sub(i)
Console.WriteLine(i.ThreadID)
End Sub)
Dim integers = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }
Dim odds = From p In integers.AsParallel() _
Where p Mod 2 = 1 _
Select p
For Each item In odds
Console.WriteLine(item)
Next
结论
Visual Basic 10 针对 DLR 作了更多的创新和优化,并在 COM 互操作性方面进行了改进。Visual Basic 10 在很多语言特性上已经和 C# 同步,这使得 Visual Basic 更加具备实力成为世界上一流的开发语言工具。