日期:2012-07-08  浏览次数:20546 次

如果你以前经常使用Visual Basic的话,你会发现VisualBasic .Net有点熟悉,又有一点陌生。在可以利用许多以前就具备的技巧和知识的同时,仍然有很多东西要学。

许多公司花费了大笔的资金投资于Visual Basic6.0编写的软件,这些公司将面临如何处理这些已存在的软件的问题。我在介绍Visual Basic .NET新特点的同时,将会介绍影响把代码移植到Visual Basic .NET的关键所在。正如你将看到的,会有很多问题要考虑。随着编程语言变得更加一致、强大和友好,你会发现把Visual Basic 6.0项目改写成Visual Basic .NET项目需要很大的努力和技术。如果顺利的话,你将有幸在不远的将来从零开始编写一个VisualBasic .NET的项目。

新的便利:
我首先将介绍用一行代码实现声明并初始化变量的新语法。尽管许多初学者会认为这种语法是理所当然的,但实际上那些已习惯于在Visual Basic用两行代码来声明和初始化变量的程序员会对此感到很欣慰。

这儿是利用了Visual Basic .NET语法优势的三个例子:
Dim x As Integer = 10
Dim obj1 As Class1 = New Class1
Dim obj2 As New Class2


请注意,与前两行不一样,最后一行用的是在Visual Basic 6.0中合法的语法,它在Visual Basic .NET中同样是合法的。然而,值得注意的是,这儿的As New语句在Visual Basic .NET and Visual Basic 6.0中的处理是不同的,许多有经验的程序员反对使用As New语句,因为它将导致初始化的延迟,进而导致较低的执行效率,并给调试程序带来了许多困难。

好消息是As New语法在Visual Basic .NET中并不会造成初始化的延迟,因此不会导致相同的问题。在看前面的例子时,你应该注意第三行,它用了As New语句,但与前面几行具有一样的执行效率。当你在Visual Basic .NET中使用As New语句时,这个对象将在执行下一行之前被创建、初始化,并指派给你的变量。

这种方便的初始化语法也可以被用在类或结构的定义中。正如你想得那样,语法应该是这样的:
Class Class1
Private Field1 As Integer = 10
Public Field2 As Class1 = New Class1
End Class


另一点值得注意的是,当你在同一行声明几个变量时,他们应该是相同类型的变量,请看这个例子:
Dim x, y, z As Integer

三个变量都被声明成integer类型,你不再需要担心前两个变量偶然会被当作variant类型。实际上,你不用担心有什么变量会被当作variant类型处理,因为variant类型不再被CLR编程模型所支持。现在的通用类型是System.Object.
在Visual Basic .NET新增加的语法中,我最喜欢的一点是现在函数可以用Return来向它的调用者返回一个值。请看下面的例子:
Function MyFunction() As String
Return "This is my return value"
End Function

这个例子和用其他语言(比如C语言)一样,Return语句将结束函数的执行,并把控制权返回给调用者。我觉得使用Return语句与我们在VisualBasic的早期版本中的做法相比要方便得多。正如你记得的,在以前的版本中,要返回给调用者的值必须在函数的内部被赋给函数名。由于在VisualBasic .NET中使用了Return语句,你可以很容易地实现更改函数名或把代码从一个函数中复制、粘贴到另一个函数,而不需要搜索函数的内容并替换原来的函数名。

消除矛盾
正如我在二月份的文章中提到的那样,在把一个对象指派给一个变量时,Visual Basic .NET既不需要,也不允许你用Set这个关键字。VisualBasic 6.0 和Visual Basic .NET的编译器有许多方面不一样,这就是其中之一。请看下面的代码:
Dim obj1, obj2, obj3, obj4 As Class1
obj1 = New Class1
obj2 = obj1
Set obj3 = New Class1
Set obj4 = obj3


第二行和第三行代码在Visual Basic .NET中是合法的。但在VisualBasic 6.0中编译时,它们将导致运行期错误。第四行和第五行的代码在VisualBasic 6.0中是合法的,但在Visual Basic .NET中却不能通过编译。正如你想象的,在把代码从VisualBasic 6.0移植到Visual Basic.NET时,需要特别注意对Set语句的改写。

在用Visual Basic .NET编写了六个多月的程序后,我发现自己仍然会使用Set语句,老习惯是不容易被改掉的。而且由于工作的关系,有好几次我得在同一天即用VisualBasic.NET,又用Visual Basic 6.0编写程序。不停地来回往复真地很困难。

在参数传递中括号的使用也发生了变化,这也给代码移植增加了困难。你们中的许多人在经过多年的编程之后已经习惯了调用函数和子程序的规则和特点。VisualBasic.NET小组觉得应该实现调用方法的一致性。

在Visual Basic. NET中,参数传递的规则很简单。当你调用一个函数或子程序并需要传递一个或多个参数时,必须用小括号把参数括起来。当调用一个不需要参数的函数或子程序时,小括号可以被省略。你不得不承认,与早期版本的VisualBasic中的规则相比,这些规则更直截了当,也更容易去学。

值得注意另一点是参数传递的默认方式也改变了。比如,当一个方法被定义成下面这种样式时,参数是如何被传给调用者的。
Sub Method1(Param1 As Integer)
' implementation
End Sub

在Visual Basic以前的版本中,Param1是引用传递的。也就是说在执行Method1时,改变这个integer类型的参数将导致调用者中相应的实际参数的值的改变。而在VisualBasic.NET中,默认的参数传递方式变成了值传递。也就是说执行Method1时,只是值被传递给了Param1,并且在Method1中改变Parame1的值不会改变调用者中相应的实际参数的值。很明显,在把VisualBasic 6.0中代码移植到Visual Basic.NET,这种参数传递默认方式的改变将破坏一些代码的语义。

请注意,在上一个例子中,被传递到参数的是一个值而不是地址。基本类型比如Byte,Integer,Double, and Boolean都是值类型。用户定义的枚举和结构类型也是值类型。在以值传递方式传递时,变量总是被复制。

当你传递的参数是基于类时,情况就不同了。基于类的参数是引用类型而不是值类型。它们被用来传递对象的引用。如果一个调用者传递了一个对象的引用给一个用了值传递方式的方法,在这个方法的实现中,对象的状态可能被改变。这种状态的改变将反映到调用者中。因此,无论你把参数声明成值传递还是引用传递,注意值类型还是引用类型之间的区别是很重要的。

尽管在方法中仍然可以使用可选参数,这仍是值得注意的地方。与VisualBasic 6.0不同,使用可选参数需要一个默认值。在同一行中,Visual Basic.NET不支持IsMissing函数,也就是说你区分不出一个省略了参数的调用和一个给参数传了默认值的调用。

如果你考虑在方法中使用可选参数,你应该考虑重载方法。一旦你知道了重载方法的好处和语法,你也许就会停止在方法中使用可选参数。

更高级别的类型保护
许多使用Visual Basic的开发者希望在每一个VisualBasic的源文件的开头能有一个Option Explicit语句。Option Explicit的应用可以区别对待真正的开发者和临时用户。和以前的版本不同,Visual Basic.NET缺省就使用Option Explicit。
在编译时默认使用Option Strict是Visual Basic.NET的另一个特点。使用了Option Strict后,缩小转换就被禁止了,因为它可能会导致数据或精度的丢失。请看下面的例子:
Dim x As Double
x = 20.1
Dim y As Integer
' implicit narrowing conversion
y = x ' doesn't compile under O