【转】VB6和VB.NET的区别

来源不详。

总览:
    本文推荐给那些准备将自己的应用移植到Visual Basic.NET中的Visual Basic开发者。文章中包括
Visual Basic.NET升级工具的信息的介绍以及将Visual Basic 6结构平滑升级到Visual Basic.NET 的指导
    在打开Visual Basic 6.0工程时Visual Basic.NET会自动升级,但是在绝大多数情况下你需要对在Visual 
Basic.NET下打开的Visual Basic 6.0程序做一些改动。这篇文章的用途就是时你对原来的程序的改动尽可能的
少以及有效。
注:Visual Basic.NET仍然处于开发中,所以下面的一些细节可能还会有改动,下面的指导不保证在最终的产品出
来后代码不需要改动。


什么是Visual Basic.NET?
    Visual Basic.NET是下一代的Visual Basic。而并不是简单的在Visual Basic 6.0上在添加一些新特性而已,
微软重新设计了产品以便使开发者能够更加容易的开发分布式应用,例如基于WEB的程序以及多层系统。
    Visual Basic.NET中有两种窗体包,Windows窗体以及Web窗体;一个新版的ADO用于接受离线数据源;新的语
言,移走了原来的关键字,提高Type数据的安全性以及提供低级别结构以满足高级别开发者的需求。
    这些新的特性为Visual Basic开发者提供了新的开发窗口:通过Web窗体以及ADO.NET,你可以快速开发可扩展
的Web站点;通过继承,该语言实现了真正的支持面向对象编程(object-oriented programming);Windows窗体
本身支持可视继承;现在展开程序就象拷贝可执行文件和控件到另一个目录那样简单。
    Visual Basic.NET现在完全集成在其它的Microsoft Visual Studio .NET语言中,不仅可以通过不同的语言
开发组件,而且通过交叉语言继承,你可以从用一种语言编写的类中派生用另一种语言编写的类。

为什么Visual Basic.NET不提供100%的继承性?
    当在设计Visual Basic.NET时有两个方向:翻新以及完全新建。为了体供给用户尽可能多的新特性(例如继
承以及线程),为了提供对新平台的完全访问,以及为了使Visual Basic能够完全转移到下一代的Web应用中。正
确的选择是完全新建。

    例如,很多在Windows窗体中的新特性可以通过在现有的代码中添加新控件以及属性来实现。但是这样就会牺
牲新的Windows窗体的很多内在特性,例如安全以及可视继承性。

    一个重要的目标是使Visual Basic代码可以完全集成到用其它语言编写的代码中,例如Microsft C#(读C Sharp)
或者Visual C++。以及让Visual Basic开发者可以完全而且简单利用.NET框架的功能,而不需要象原来那样使用
Windows API调用。所有的Visual语言将与其它面向通用运行时语言(Common Language Runtime)的语言使用相同
的数据定义类型、数组、用户自定义数组、类以及界面。不过这样就要做一些牺牲,例如固定长度字符串以及以非
0数为下界的数组将不再被支持。

    Visual Basic现在已经成为一个真正面向对象语言,一些不一致的特性,例如 GoSub/Return语句以及DefInt
已经从新语言中移走了。
    这样的结果是使Visual Basic更加具有活力,使其成为一种开发基于Windows应用的最有效的工具之一,同时
也是开发下一代的Web站点的最佳工具。

升级到Visual Basic.NET
    Visual Basic.NET原则上可以使传统的Windows开发者转移到建立下一代Web以及多层应用中。所以,你的代码
需要升级以适应Visual Basic.NET
    在你使用Visual Basic.NET打开Visual Basic 6.0工程后,通过自动升级工具可以一步步的升级并建立一个新
的基于Visual Basic.NET的工程。这个升级是单向的,既新的Visual Basic.NET工程无法再在Visual Basic 6.0中
打开。
    当工程升级后,Visual Basic.NET会修改语法的改变以及将Visual Basic 6.0窗体转换为Windows窗体。在通
常情况下,你还需要手工做一些修改,因为自动升级工具不可能替你做所有的事情。
    为帮助改变原来代码,当你的工程升级以后,Visual Basic.NET会在工程中添加“升级报告”列出所有的问题,
同时在代码中添加注释提示你需要做的改动,这些注释会以“TO DO”列表形式列出在任务列表窗口中,所以你可
以很容易的需要改变的部分,要想浏览相关的代码只需要双击任务列表中的相关项就可以了。每一个任务以及升级
报告中的列表项都有相关的在线帮助标题以给你更多的帮助。

让Visual Basic 6.0和Visual Basic.NET同时工作
    Visual Basic.NET支持升级Visual Basic 6.0生成的工程,如果你的工程是在VB 1-5下编写的,你需要首先升
级道Visual Basic 6.0工程,编译、保存后再升级到Visual Basic.NET。
    Visual Basic.NET和Visual Basic 6.0可以安装在同一系统下并可以同时运行。同样的,利用较早版本或者其
它语言编写的COM组件也可以集成到Visual Basic.NET中。例如你可以拖-放一个Visual Basic 6.0编写的ActiveX
控件到Visual Basic.NET的Windows窗体中,在Visual Basic.NET的类中使用Visual Basic 6.0的COM组件。
    Visual Basic.NET编译的组件同Visual Basic 6.0编译的组件有一点点的不同,Visual Basic.NET对象是通过
垃圾收集方式释放的,所以在对象被删除到对象真正被从内存中释放之间或许会有一定的延迟。
    另外,Visual Basic.NET提供了Visual Basic.NET组件同Visual Basic 6.0之间的二进制兼容性。现在展开一
个组件变的比以往更加容易,配置一个组件文件只需要简单的拷贝文件到目录就可以了(不需要regsvr32)。将组
件升级到新版本之需要以新文件覆盖就文件就可以了。你所要做的只是确定新组件的类同方法同旧组件兼容。


结构介绍
    .NET平台提升了上一个版本平台的结构,对于应用的可伸缩性和分布特性提供了更好的支持。例如离线数据访
问、基于HTTP的消息传递文件配置。要获得以上特性,你需要使用Visual Basic.NET。


基于浏览器的应用
Visual Basic 6.0和Visual Studio 6提供了以下的技术用于建立基于浏览器的Internet和Intranet应用:
Webclasses
DHTML projects
ActiveX documents
Active Server Pages (ASP) 

    Visual Basic.NET中引入了ASP.NET,ASP.NET是增强版的ASP,并加入到了Web窗体(Web Forms)结构中,Web
窗体是.NET架构中非常重要的一个组成部分。一个Web窗体包含两个部分:HTML文件和源程序文件。HTML文件用于
描述页面;源程序文件用于响应、控制页面事件。建立一个Web窗体同现在建立一个VisualBasic窗体一样简单。
它的WYSIWYG 界面设计方式同现在的Visual Basic是一样的。下面的图片演示了一个Web窗体的设计:

    Web窗体运行于服务器上,产生基于HTML3.2标准的HTML页面发送到客户端。这一点同ASP相同,但是由于Web程
序是编译执行的,同解释执行的ASP比较起来速度要快很多。

    下面是对将Visual Basic 6.0开发的基于浏览器的应用无缝转移到Visual Basic.NET上的一些介绍以及结构方
面的建议。

    我们建议你使用微软多层构架来开发你的应用,利用ASP来开发界面,同时使用Visual Basic 6.0或者Visual 
C++ 6.0开发的COM组件,Visual Basic.NET完全支持ASP,你可以同时使用ASP、ASP.NET、Web窗体来扩展你的应用。
同时Visual Basic 6.0或者VC6商用组件可以不经升级获修改直接在Visual Basic.NET中使用。

    包含DHTML页面以及客户端DLL的DHTML 应用不能自动升级到Visual Basic.NET。我们建议你在Visual Basic 
6.0下开发这些应用。同DHTML工程一样,ActiveX Documents不被Visual Basic.NET支持。不能自动升级。我们建
议:或者在Visual Basic 6.0下开发ActiveX Documents或者将ActiveX Documents转换为用户自定义控件。不过 
ActiveX documents 和 DHTML应用程序可以集成到Visual Basic.NET技术中。

    Web类(Webclasses)在Visual Basic.NET中将不再存在。Web类应用将升级到ASP.NET;不过,在自动升级后
你还需要做一些更改。现存的Web类应用可以集成到Visual Basic.NET的Web窗体和ASP应用中,但是在新工程中,
我们建议在新工程中使用ASP的Windows DNA平台。关于更多的关于Windows DNA的信息,请访问微软DNA站点:
http://msdn.microsoft.com/isapi/gomscom.as...sp?Target=/dna/

客户/服务器工程
Visual Basic 6.0提供以下技术用于建立客户端/服务器应用:
Visual Basic窗体
Microsoft Transaction Server (MTS)/COM+中间层对象
用户控件

    Visual Basic.NET提供了新的窗体包:Windows窗体。相对于Visual Basic 6.0的窗体,Windows窗体使用不同
的对象模块,不过绝大部分是兼容的。当你的工程升级时,Visual Basic窗体自动升级到Windows窗体。下面是
Windows窗体的示例:

    对于开发中间层的MTS and COM+ 服务器组件,Visual Basic.NET提供了更强大的支持。使用统一的调试器,
你可以从 客户端到MTS/COM+组件再到客户端进行步进调试。同时集成调试器也支持在MTS 和 COM+ 组件内部进行
调试(组件需要以native code方式编译,包含符号调试信息以及不进行优化)。

    Visual Basic.NET同样也提供了新的中间层组件:Web Services(Web服务器)。Web服务器包含在ASP.NET中,
其结构如下图所示:

    通过使用HTTP传递允许方法请求可以通过防火墙传递。数据的传递使用基于工业标准的XML,允许其它语言以
及平台访问它们的功能。尽管不再支持MTS事务,但是你还是有理由将你的应用升级到Web Server,如果你不仅需
要分布式事务处理而且需要跨平台操作。通过Visual Basic.NET你可以通过简单的拖-放操作来完成。

    当你的工程升级后,用户控件会升级到Windows控件;然而,自定义属性标记设置以及加速键设定不会升级。


单层应用
Visual Basic 6.0支持建立以下类型的单层应用程序:
单层数据库应用程序
Visual Basic插件
普通的应用程序以及游戏。

    单层数据库程序的代表就是使用Visual Basic访问微软Access数据库。这些应用可以有限制的升级到Visual 
Basic.NET
    现在Visual Basic.NET集成开发环境(IDE)已经完全集成为Visual Studio.NET IDE的一部分,Visual Basic.NET
包含新的中性语言(language-neutral)的扩展模块Visual Basic.NET的插件现在就等同于Visual Studio.NET 
add-ins,你可以利用Visual Studio.NET中的任何语言来开发插件。例如,你可以编写一个Visual Basic.NET插件
来绘制Visual C#窗体的颜色或者为VB类添加注释。为了支持这些新的功能,Visual Basic.NET已经不再支持旧的
扩展模块,你需要更改原来程序中的扩展对象。

    很多程序被规于应用程序(Utility programs)。应用程序需要操作文件、设置注册表。对此,Visual Basic.NET
也提供了新特性。例如意外句柄可以捕捉文件系统错误,使用注册表类可以勇于操控注册表。需要注意的是,一些
依赖于系统性能特征(performance characteristics)的程序,例如游戏需要做改进,因为Visual Basic.NET提
供了新的系统性能特征,对于Visual Basic.NET下的游戏开发,你可以使用微软DirectX7,或者使用新的GDI:GDI+,
GDI+包含了很多新特性,对简单的2-D游戏提供了Alpha混合、反锯齿支持以及更多的图像文件格式的支持。

数据库操作
Visual Basic 6.0提供了以下类型的数据库访问方式:
ActiveX Data Objects (ADO)
Remote Data Objects (RDO)
Data Access Objects (DAO) 

    Visual Basic.NET包含了增强版的ADO,称之为ADO.NET。ADO.NET的目标是操作离线数据。同时对于ADO的分布
应用提供了更强大的支持。ADO.NET提供了绑定数据库到Windows窗体控件和Web窗体。
    通过做一些小的更改,DAO,RDO,ADO仍然可以在Visual Basic.NET中使用。然而,Visual Basic.NET不支持DAO
和RDO数据库到控件、数据库控件或者RDO用户连接的绑定。我们建议在应用中包含DAO和RDO的应用或者仍然使用
Visual Basic 6.0开发或者再升级到Visual Basic.NET前将它们更改为ADO数据绑定。
语言方面的改进
    我们在很多的编程论坛或者新闻组中可以看到C++的拥护者将VB称为一个玩具语言(Toy Language)。其中VB最
被人诟病的是它不真正支持面向对象编程(oop)。
在新的Visual Basic中,这些都将成为过去。Visual Basic.NET将真正支持oop。继承(inheritance)、多态
(polymorphism)以及重载(overloading)。当然还不止这些。包括一些新的数据结构、结构性的错误控制(Error 
Handing)以及线程。这些都将被新的VB所支持。

继承
    假设你编写了一个只包含一个函数的名称为BaseClass的基本类:
    
    Function GetCustomerName()
    ' Do some stuff
    End Function

    如果你想建立一个新类,并使用BaseClass中的GetCustomerName函数。但有不想重写一编代码。那么通过继承,
你可以这样编写新类:

    Inherits BaseClass

    Function GetCustomerID()
    ' Do some stuff
    End Function

重载
    重载就是建立两个具有同样你名称但是参数属性不同的函数的过程。假设有GetCustomID函数根据输入输出用
户的ID号码。那么该函数可能有以下两种类型:

Function GetCustomerID(custname as string) As Integer
' 通过用户名获得用户ID
End Function

Function GetCustomerID(purch as long) As Integer
' 根据购物单号码获得用户ID
End Function

通过重载,你就可以根据不同类型的输入调用同一个函数。
实际上现在的VB在某种程度上提供了重载的功能,考虑下面的函数:

Function GetCustomID(vIN As Variant) As Long
    GetCustomID = vIN
End Function

你可以以下面两种方式调用

ID = GetCustomID("123")
或者
ID = GetCustomID(123)

    那么为什么还要在新版本中引进重载呢?这是因为新的Visual Basic引进了新的特性:类型安全(default 
type safety)。在Visual Basic.NET中,Variant类型将不复存在,详细的介绍看下面关于升级部分的内容。

多态
    多态是在一个类中重新定义一个函数的过程。例如你需要建立一个基于BaseClass类的子类,但是又需要重新
编写GetCustomerName函数,在新版的VB中,你就可以这样写:

Inherits BaseClass

Function GetOrders()
Overrides Function GetOrders()
...
End Function

线程
    新的Visual Basic语言结构部分将包含建立多线程,一个线程建立的范例如下:

set t = New Thread(New Threadstart
                  (AddressOf(BaseClass.Function1))

    从上面的范例还可以看到,Visual Basic.NET中的AddressOf函数将真正返回函数的指针。这在进行API调用,
例如回调函数方面将是很有帮助的。

错误处理(Error Handling)
    Visual Basic.NET的另外一个大的改进就是错误处理。Visual Basic将提供try…catch…finally结构,就象
Delphi中的那样(微软的原文是:just like those "respectable" languages :-))。例如:

Sub SafeWrite()
Try
  Open "Testfile"
  ...
  Write #1
Catch
   Kill "Testfile"
Finally
   Close #1
End Try
End Sub


升级
    当代码升级后,Visual Basic.NET会建立一个新的升级工程。下面通过几个例子来说明你的代码做了那些升级

Variant类型到Object类型
    以前版本的Visual Basic支持Variant数据类型,该类型可以设定为除了固定程度字符串外的任何原始数据类
型和Empty,Error,Nothing和Null。在Visual Basic.NET中,Object数据类型可以设定为任何原始数据类型和Empty,
Error,Nothing,Null和对象指针。当你的工程升级到Visual Basic.NET后,任何Variant定义都会改变为Object。
同样,当你在编辑器中插入代码时,Variant关键字也会被替换为Object。

Integer数据类型到Short数据类型
    在Visual Basic 6.0中,16bit数现在称为Short。32bit数称为Integer(64bit数称为Long)。当工程升级后,
数据定义会做如下改动:

Dim x As Integer
dim y as Long
更改为:

Dim x As Short
dim y as Integer

属性语法
    Visual Basic.NET对于自定义属性的语法作乐更加直观的更改,将Get和Set合而为一。例如原来的属性如下:

Property Get MyProperty() As Integer
    m_MyProperty = MyProperty
End Property
Property Let MyProperty(NewValue As Integer)
    m_MyProperty = NewValue
End Property

升级后更改为:

Property MyProperty() As Short
    Get
        m_MyProperty = MyProperty
    End Get
    Set
        m_MyProperty = Value
    End Set    
End Property

VB窗体到Windows窗体
    Visual Basic.NET包含新的窗体包,Windows窗体,Windows窗体包含内含菜单编辑器。你的VB窗体会升级到
Windows窗体。

界面
在先前的版本中,公用类界面对于用户总是隐藏的。在Visual Basic.NET中,公用类可以在代码窗口中浏览和编辑。

升级报告及注释
    当工程升级后,升级报告会添加到你的工程中,详细列出所有升级后的你所需要对代码做的更改。同时代码中
会加入注释提示你注意任何潜在的问题。这些注释自动出现在Visual Basic.NET的任务列表中。

编程介绍

使用先前绑定
    Visual Basic 6.0和Visual Basic.NET都支持对象的延迟绑定,该方法事先定义一个变量为Object数据类型,
然后在运行时将其设定为一个类。然而,在升级过程中,当访问延迟绑定对象的缺省属性时可能会产生错误。例
如假设工程中包含Form1,Form1中有一个Label对象,名称为Label1,下面的Visual Basic 6.0代码将Label的标题
设定
为"SomeText"

Dim o As Object
Set o = Me.Label1
o.Caption = "SomeText"

    在Visual Basic.NET的Windows窗体中,Label控件的Caption属性被称为Text属性。当你的代码升级后,所有
实例中的Caption属性都会转换为Text属性,但是延迟绑定对象是无类型(type-less)的,VB无法检测到对象的
类型并做更改,在这种情况下,你需要手工对代码做改动。当你使用先前绑定对象时,对象可以自动升级,如下:

Dim o As Label
Set o = Me.Label1
o.Caption = "SomeText"

    所以在程序中你需要将对象定义为适当的对象类型而不是简单的定义为Object对象类型。

    同Visual C++类似。Visual Basic.NET支持函数的重载,例如下面的一个函数具有两个形态

    Environ( Expression As Integer) As String
    Environ( Expression As String ) As String 

    Visual Basic.NET会自动检测该使用那个参数的函数。如果你传递一个正数值到Environ(),那么正数调用版
本会被调用;如果传递一个字符串,String版本会被调用。如果传递Object或者Variant数据类型到一个重载函数
将产生运行时错误。如果要想产生正确的结果就需要通过数据类型的强制转换,例如:

Dim a As String
Dim v As Variant
v = "Path"
a = Environ(CStr(v))   '正确

    对于延迟绑定的对象使用强制类型转换是一个很好的编程习惯。这就使得代码可读性更好,同时也可以非常轻
松的移植到Visual Basic.NET使用Date存储日期/时间较早版本的VB支持使用Double数据类型来存储和改变时间。
在Visual Basic.NET中,这个特性将不再支持,因为在计算机内部日期并不是以Double方式存储的,例如下面的代
码可以在Visual Basic 6.0中运行,但是在Visual Basic.NET中会产生错误。

Dim dbl As Double
Dim dat As Date
dat = Now
dbl = dat      '错误,不能将一个Date变量赋予一个Double变量
dbl = DateAdd("d", 1, dbl)   '错误,Double变量不能用于日期函数
dat = CDate(dbl)   '错误 CDate函数不能将Double变量转换到Date

    .NET架构提供了ToOADate与FromOADate函数用于在double变量以及Date变量之间转换。然而这需要在升级后手
工修改,所以在存储日期时应该使用Date数据类型。

缺省属性
    在Visual Basic 6.0中,许多对象都有缺省属性,缺省属性在代码中可以省略。例如:

MsgBox Form1.Text1.Text

可以这样编写:

MsgBox Form1.Text1   

缺省属性在代码编译是决定。同样,你也可以在延迟绑定的对象中使用缺省属性,例如:

Dim obj As Object
Set obj = Form1.Text1
MsgBox obj

对于延迟绑定的对象,缺省属性在程序运行时决定。

    Visual Basic.NET不支持缺省属性,当你的工程升级后,Visual Basic.NET会自动决定缺省属性,但是对于延
迟绑定的对象无法自动解决决定缺省属性的问题。在这种情况下,你需要自己来修改代码。更加复杂的是,很多库
是通过 _Default属性来实现缺省属性的。_Default象是一个代理,它将调用传递给真正的缺省属性。所以当你的
工程升级后,一些属性会被更改为 _Default。代码还是象往常那样工作,只是代码不如原来的实际属性易读。

Dim obj As Object
Set obj = Me.Text1
MsgBox obj   '不好的代码,使用缺省属性
MsgBox Me.Text1   '不好的代码,使用缺省属性

use:

Dim obj As Object
Set obj = Me.Text1
MsgBox obj.Text   '好的代码,写出了属性
MsgBox Me.Text1.Text   '好的代码,写出了属性

    虽然缺省属性不被Visual Basic.NET支持,但是带参数的缺省属性是被支持的,要了解它们之间的区别,下面
是范例:

Dim rs As ADODB.Recordset
rs("CompanyName") = "SomeCompany"
rs!CompanyName = "SomeCompany"

实际上等于:

Dim rs As ADODB.Recordset
rs.Fields("CompanyName").Value = "SomeCompany"
rs.Fields!CompanyName.Value = "SomeCompany"

因为Value是Fields的缺省属性
对于第二种写法,Visual Basic.NET是支持的;然而第一种情况不被支持,那么正确的用法如下:

Dim rs As ADODB.Recordset
rs("CompanyName").Value = "SomeCompany"
rs!CompanyName.Value = "SomeCompany"

    象上面的范例和其它的大多数情况可以在工程升级时解决,但是你还是要避免在Visual Basic 6.0中在Object
和Variant数据类型使用缺省属性。因为升级程序无法发现并解决这些错误。

对Boolean类型数据使用AND/OR/NOT操作
    And和Or关键字在Visual Basic.NET和Visual Basic 6.0中的使用是不同的,在Visual Basic 6.0中,AND运算
既执行逻辑AND操作也执行逐位AND操作,取决于操作数(如果是Boolean类型,执行逻辑AND操作,如果是数字,执
行逐位AND操作)。在Visual Basic.NET中,AND运算只执行逻辑AND操作。对于逐位操作,在Visual Basic.NET提供
了一组操作:BitAnd, BitOr, BitNot以及BitXor 。

下面是演示这些差异的范例程序

Dim a As Integer
Dim b As Integer
Dim c As Boolean
a = 1
b = 2
c = a And b
MsgBox ("The answer is " & c)

    当上面的代码在Visual Basic 6.0下运行时,结果是False(执行逐位AND操作);然而在Visual Basic.NET下,
结果是True(执行逻辑AND操作)。
    要确定你的程序在升级后也运行结果同升级前一样,Visual Basic.NET包含了兼容函数VB6.And, VB6.Or以及
VB6.Not,这些函数执行的结果同Visual Basic 6.0下的AND/OR/NOT操作的执行结果是一样的。当代码升级后,结
果会象下面这样:

Dim a As Short
Dim b As Short
Dim c As Boolean
a = 1
b = 2
c = VB6.And(a, b)
MsgBox ("The answer is " & c)

升级后的代码会得出False的结果,同Visual Basic 6.0下运行一样

    如果不想你的代码升级后使用兼容函数,就需要确保你的AND/OR/NOT都使用在Boolean类型数据的操作中,例
如,如果上面的代码更改为下面的方式:

Dim a As Integer
Dim b As Integer
Dim c As Boolean
a = 1
b = 2
c = a <> 0 And b <> 0
MsgBox ("The answer is " & c)

当升级后,代码同原来的几乎一样:

Dim a As Short
Dim b As Short
Dim c As Boolean
a = 1
b = 2
c = a <> 0 And b <> 0
MsgBox ("The answer is " & c)

    同前面不同的是每一个操作都是在Boolean数据之间进行的,因此它们在Visual Basic 6.0中使用的都是逻辑
AND操作。所以在升级到Visual Basic.NET后不会发生改变。这样做的意义是你可以直接在Visual Basic.NET和
Visual Basic 6.0之间拷贝和粘贴代码,你的代码会运行的更快因为使用的是本地的AND操作而不是兼容函数。

    另外一个需要考虑的问题是对于函数结果的AND/OR/NOT 操作的问题,例如下面的范例:

Dim b As Boolean
b = Function1() And Function2()

    在Visual Basic 6.0中,Function1和Function2的结果都会执行后再将结果进行AND操作。在Visual Basic.NET
中,只有当Function1的结果为True时才会计算Function2。因为Visual Basic.NET中的AND运算执行的是逻辑AND操
作,如果Function1结果为False,AND结果肯定是False,为了加快速度就不再执行Function2的了。但是如果
Function2另有目的,例如用于避免某些错误,那么就会出现不可预知的错误,那么上面的代码升级后就会象下面
的样子:

Dim b As Boolean
b = VB6.AND(Function1(), Function2())

为了不在升级代码中出现兼容函数,原来的代码需要做如下的改动:

Dim b As Boolean
Dim c As Boolean
Dim d As Boolean
c = Function1()
d = Function2()
b = c And d

    另一个需要注意的是在Visual Basic.NET中,True值将不再是-1而是1。做这个改变是为了使Visual Basic.NET
能集成在 .NET语言中。因为有这个改变,你需要再你的Visual Basic 6.0工程中使用常量True而不是-1来表示真
值,使用Boolean类型而不是整数类型变量保存Boolean数据。下面的代码说明了Visual Basic 6.0和Visual Basic.NET
之间的不同:

Dim i As Integer
i = True
If i = -1 Then
    MsgBox ("True")
Else
    MsgBox ("False")
End If
在Visual Basic 6.0中,结果为True,而在Visual Basic.NET中结果为False。

如果对代码做如下改动,程序在两种语言下运行都会显示True

Dim i As Boolean
i = True
If i = True Then
    MsgBox ("True")
Else
    MsgBox ("False")
End If

通过上面的范例可以看出在程序中需要注意两点:
1、使用常量True和False来判断是否而不要使用0和-1
2、使用Boolean类型变量储存Boolean数值而不要使用Integer类型变量
如果在你的程序中没有这么做的话,在升级后你还需要做大量的手工改动

避免Null传播(Propagation)
    先前版本的VB支持Null传播。Null传播的前提是null值使用在表达式中,表达式的结果将是Null,例如下面
的范例,结果V都将是Null

Dim V
V = 1 + Null
V = Null + Right$("SomeText", 1)
V = Right("SomeText", 0)

    Null传播在Visual Basic.NET中将不再被支持。象上面的语句1+Null会产生一个类型错误。另外在Visual 
Basic 6.0中有两个求左值的函数:Left和Left$前者返回值为Variant类型并且可以为空,Left$函数返回值为String
类型。在Visual Basic.NET中,只有一个Left函数,该函数总是返回String类型值

    为了使程序兼容Visual Basic 6.0以及Visual Basic.NET,你需要在代码中加入对Null检测的代码,在Visual 
Basic.NET中,下面的函数将不再返回Null值:

Chr Mid 
Command Oct 
CurDir Right 
Date RTrim 
Environ Space 
Error Str 
Hex Time 
LCase Trim 
LTrim UCase 

由于数据库中的数据可以包含Null值,所以你需要在程序中对获得的数据加入代码检测其值是否为Null。

使用以0为下界的数组
    Visual Basic 6.0允许你使用任何整数数字作为一个数组的上界和下界。同样你也可以通过ReDim将一个Variant
重新定义为数组。为了能够同.NET平台下的其它语言协同工作,Visual Basic.NET数组必须以0作为下界,而且只
有一个变量事先定义为数组后才可以使用ReDim函数重新定义。虽然这样限制了数组定义的灵活性,但是这样可以
在Visual Basic.NET和.NET下的其它语言之间传递数组。下面的范例说明了新的定义数组的约束:

Dim a(1 To 10) As Integer   '错误:下界必须为0
Dim v
ReDim v(10)   '错误,在没有定义v为数组前不能使用ReDim
Dim b(10) As Integer   '正确
ReDim b(5) As Integer   '正确

    另外,在Visual Basic 6.0中, Dim (0 to 10) As Integer定义了包含11各整数的数组,索引从0到10。同样
的定义在Visual Basic.NET下建立一个包含10个整数的数组,索引从0到9。

    基于上面的改变,Option Base 0|1已经从Visual Basic.NET中删除了。

    当你的代码升级到Visual Basic.NET后,以0为下界的数组不会改变。如果数组下界非0的话,数组会升级到一
个兼容类,如下:

Dim a(1 To 10) As Integer
改变为:

Dim a As Object = New VB6.Array(GetType(Short), 1,10)

    兼容数组类比本地数组操作起来要慢很多,同时在程序中使用它也有限制。例如你不能将一个兼容数组类作为
参数传递到一个以数组作为参数的函数,你也不能传递一个兼容类到Visual C#或者Visual C++类中。

    基于以上原因,你需要在你的Visual Basic 6.0代码中使用以0为下界的数组,避免使用ReDim定义数组,避免
使用Option Base 1语句。

使用VB常量而不要使用它们所代表的值
在写代码的时候,尽量使用VB常量而不要使用它们所代表的值。例如你要在运行时将一个窗口最大化,使用:

Me.WindowState = vbMaximized   'Good: Constant name

而不要使用:

Me.WindowStyle = 2   'Bad: Underlying value
Me.WindowStyle = X   'Bad: Variable

    在Visual Basic.NET中,一些属性和常量的数值发生了改变;例如True的值由-1变为了1。在你的代码升级到
Visual Basic.NET后,大部分的常量会自动更改;然而如果你使用的是常量代表的数值而不是常量名,那么你就要
做大量的手工更改工作。

用户自定义数据类型中的数组和固定长度字符串
    为了使Visual Basic.NET数组和数据结构完全兼容Visual Studio.NET,固定长度字符串在新语言中不再被支
持。在大多数情况下者不是问题,因为Visual Basic.NET提供了兼容固定长度字符串定义的类,那么代码:

Dim MyFixedLengthString As String * 100

升级后会变成这样:

Dim MyFixedLengthString As New VB6.FixedLengthString(100)

    然而,在数据结构(例如用户自定义数据)中使用固定长度字符串类可能产生错误。因为在用户自定义数据结
构建立时类不会被建立。用户自定义数据中的固定长度数组也会产生同样的问题。

    当你的代码升级后,在代码中的用户自定义数据类型中如果有固定长度的数组和字符串的话,在定义位置会添
加注释提醒你在使用用户自定义数据类型前首先对字符串或者数组进行初始化。然而,你可以在你的Visual Basic 
6.0的用户自定义类型中将固定长度的字符串定义改变为字符串定义,将固定长度数组定义改变为未初始化数组来
避免升级产生后产生上面的问题。例如:

Private Type MyType
    MyArray(5) As Integer
    MyFixedString As String * 100
End Type
Sub Bar()
    Dim MyVariable As MyType
End Sub

升级后会变为:

Private Type MyType
    MyArray() As Integer
    MyFixedString As String
End Type
Sub Bar()
    Dim MyVariable As MyType
    ReDim MyVariable.MyArray(5) As Integer
    MyVariable.MyFixedString = String$(100, " ")
End Sub   

Avoid Legacy Features
避免使用从原始Basic继承的特性,如下的关键字在新版本语言中将不再出现:

Def
Computed GoTo/GoSub
GoSub/Return
Option Base 0|1
VarPtr, ObjPtr, StrPtr
LSet 

Windows APIs
    大多数的API调用可以象在Visual Basic 6.0中一样使用,因为数据类型发生了改变。在Visual Basic 6.0中
的Long类型在Visual Basic.NET中定义为Integer类型。在升级过程中这些定义会自动改变,例如:

Private Declare Function GetVersion Lib "kernel32" () As Long
Function GetVer()
    Dim Ver As Long
    Ver = GetVersion()
    MsgBox ("System Version is " & Ver)
End Function

改变为:

Private Declare Function GetVersion Lib "kernel32" () As Integer        
Function GetVer()
    Dim Ver As Integer
    Ver = GetVersion()
    MsgBox("System Version is " & Ver)
End Function

    除了数字类型的升级外,Visual Basic 6.0还支持固定长度字符串类型,该类型升级到Visual Basic.NET后
会定义为固定长度字符串兼容类。

所以在Visual Basic 6.0代码中最好使用通用字符串定义,例如:

Private Declare Function GetUserName Lib "advapi32.dll" Alias _
"GetUserNameA" (ByVal lpBuffer As String, ByRef nSize As Long) As Long
Function GetUser()
    Dim Ret As Long
    Dim UserName As String
    Dim Buffer As String * 25
    Ret = GetUserName(Buffer, 25)
    UserName = Left$(Buffer, InStr(Buffer, Chr(0)) - 1)
    MsgBox (UserName)
End Function

上面的代码出现了固定长度字符串,最好更改为:

    Dim Buffer As String
    Buffer = String$(25, " ")

升级到Visual Basic.NET后会称为下面的样子:

Declare Function GetUserName Lib "advapi32.dll" Alias _ 
"GetUserNameA" (ByVal lpBuffer As String, ByRef nSize As Integer) As Integer
Function GetUser()
    Dim Ret As Integer
    Dim UserName As String
    Dim Buffer As String
    Buffer = New String(CChar(" "), 25)
    Ret = GetUserName(Buffer, 25)
    UserName = Left(Buffer, InStr(Buffer, Chr(0)) - 1)
    MsgBox(UserName)
End Function

    在有些情况下,Visual Basic.NET能够更好的控制传递字符串到API调用,因为你可以通过ANSI 和UNICODE 
关键字定义字符串传递的方式。

有三种情况需要对代码最手工改进。
1、在传递给API函数的自定义数据类型定义中包含固定长度字符串和数组。在Visual Basic.NET中你需要对自定
义数据类型定义中的每一个固定长度
字符串和数组添加MarshallAs 属性。
2、在定义中使用As Any声明。该种声明不再被Visual Basic.NET支持,变量定义为As Any通常是为了传递一个既
可能是字符串也可能是Null的变量,在Visual Basic.NET中,你可以定义两个不同类型的API,一个为Long类型,
一个为String类型,以API函数GetPrivateProfileString 为例:

Private Declare Function GetPrivateProfileString Lib "kernel32" Alias 
   "GetPrivateProfileStringA" (ByVal lpApplicationName As String, ByVal 
      lpKeyName As Any, ByVal lpDefault As String, ByVal 
         lpReturnedString As String, ByVal nSize As Long, ByVal 
            lpFileName As String) As Long

你可以删除As Any而代之以定义两个不同的函数;一个接受Long数值,一个接收String树脂:

Private Declare Function GetPrivateProfileStringKey Lib "kernel32" Alias 
   "GetPrivateProfileStringA" (ByVal lpApplicationName As String, ByVal 
      lpKeyName As String, ByVal lpDefault As String, ByVal 
         lpReturnedString As String, ByVal nSize As Long, ByVal 
            lpFileName As String) As Long
Private Declare Function GetPrivateProfileStringNullKey Lib "kernel32" 
   Alias "GetPrivateProfileStringA" (ByVal lpApplicationName As String, 
      ByVal lpKeyName As Long, ByVal lpDefault As String, ByVal 
         lpReturnedString As String, ByVal nSize As Long, ByVal 
            lpFileName As String) As Long

当你希望传递Null数值时,使用GetPrivateProfileStringNullKey。

3、如果你的程序中有诸如建立线程、Windows子类(subclassing),消息钩子等API调用时,这些函数在
Visual Basic.NET下可能会产生运行时错误。很多这些API在Visual Basic.NET或者.NET架构中有等价的函数。

窗体与控件
    Visual Basic.NET包含了一个新的窗体包:Windows窗体。Windows窗体与Visual Basic 6.0窗体间保持了最
大的兼容性;然而,还是有一些需要提出的关键差异:
    Windows窗体不支持OLE container控件;你需要在Visual Basic 6.0应用中避免使用该控件。
    在Windows窗体中没有Shape控件。矩形和圆角形状控件会升级为Label控件,椭圆和圆形无法升级。你需要在
Visual Basic 6.0应用中避免使用该控件。
    在Windows窗体中没有Line控件。横线条和竖线条控件会升级为Label控件,斜线条无法升级。你需要在Visual 
Basic 6.0应用中避免使用该控件。

    Windows窗体提供了新的图形命令取代Circle, CLS, PSet, Line以及Point。因为新的对象模块同Visual Basic 
6.0是不同的,这些方法无法被升级

    对于Timer控件,将Interval属性设置为0不能使Timer控件停止运行而是将时间间隔设定为1。所以在Visual 
Basic 6.0中,需要通过设置Enabled属性为False而不是将Interval属性设置为0来停止Timer运行。

    Windows窗体包含两种菜单控件,MainMenu(窗口菜单)和ContenxtMenu(弹出菜单)。而Visual Basic 6.0只包
含一种菜单控件:Menu。Menu可以以窗口菜单方式也可以以弹出菜单方式打开。工程升级后Menu会升级到MainMenu。
但是你不能以弹出方式打开MainMenu;你需要手工建立弹出菜单。

Windows窗体不支持动态数据交换(DDE)。
Windows窗体不支持Form.PrintForm方法

    虽然Windows窗体在功能上支持拖-放但是对象模块同Visual Basic 6.0有很大的不同,所以Visual Basic 6.0
中的拖-放属性以及方法无法升级。

    .NET架构对Clipboard对象进行了升级,对剪贴版的操作比Visual Basic 6.0的Clipboard对象提供了更多的函
数和支持。因为对象模块的不同,Clipboard声明无法自动升级


    Windows窗体不支持在运行时对窗体和控件的Name属性进行访问,这样你就不能通过Name属性访问控件集合中
的控件(这个功能在.Net的System.Reflection类中提供)

    为了保证你的窗体在升级后保持正确的尺寸,你要确保在程序中将缺省的缩放比例(ScaleMode)设定为Twips。
当升级后,Visual Basic.NET将度量单位从Twips转换为pixels

    上面就是关于Visual Basic.NET的说明,从上面的介绍可以看到,相对于以前的版本,这一次的的Visual Basic
可以说是有了重大的革新(而且似乎有一些方面在向Delphi看齐)。它提供了以前版本从来没有的面向对对象编程,
强大的错误处理,同VC++ C Sharp更紧密的集成。但是也牺牲了很多原来Basic一直都有的特性。不过总的来看,还是
值得升级到Visual Basic.NET的。如果最终的版本能够实现他们所说的那样,我会给Visual Basic.NET打4颗星。

posted @ 2014-07-24 10:06  Spacecup  阅读(1226)  评论(0编辑  收藏  举报