扫一扫
分享文章到微信
扫一扫
关注官方公众号
至顶头条
概要
VB正在不断地发展中,它具备了以前VB编程人员作梦都想拥有的性能,想象一下你将随心所欲的利用这些性能,是不是很令人激动?然而,这个计划于2001年第四季度上市销售的VB版本可能会给你带来些小麻烦,因为要完全掌握它需要一个较长的学习周期,而且其中包括了一些微妙的变化,你可能在使用他们的时候出现错误。
需要准备的条件:建议获得Visual Basic.NET beta 版,这些内容对所有VB程序员都是有用的。
Microsoft .NET平台的涵盖面很广,而且很难预测它的真正意义。我们注意到,现在有很多关于.NET的不正确的理解。因此在这篇文章里,我们将把给你一个VB.NET到底是些什么的概念,从头到尾说一说它是什么、它能干什么以及怎样才能充分发挥它的优点。我们要特别地细看一下IDE的改变、面向对象特征、底层结构的改变、一些“现代化”的语法以及包装和分发方面的增强。我们将讨论这些功能能为你做什么,解释他们的优点与不足。由于这些改变是如此之大,而且涉及方方面面,因此希望这一篇文章能满足你全部的要求是不现实的,要了解这方面全部的知识请参阅有关文章和书籍。
Visual Basic.NET 和你现在所知的开发工具完全不同,并且这个新版本会改变你的未来。到底有多大不同?如果你觉得从VB3迁移到VB4是一个很大的变化,那这次VB.NET会让你感到震惊。这次升级与其说是VB的一个新版本,还不如说是迁移到一个新平台上,你所面临的情况就和从DOS迁移到Windows差不多。
VB获得了继承能力
VB.NET预期拥有的第一新功能就是继承能力。继承是VB开发者长期以来要求得最多的功能。判断一下对继承的要求是不是像早些时候对本地化编译器的要求一样将是一件很有意思的事,后者,当Microsoft提供了一个以后,你就几乎听不到多少这方面的言语了。
Visual Basic现在是真正的面向对象语言了。过去,你可以通过使用VB的界面继承性创建伪实现的对象继承,但现在不必这样做了。
Visual Basic.NET 现在提供大量面向对象功能,包括应用程序继承,它允许你从其它类导出你想创建的类。像在其它面向对象语言里一样,你能覆盖基类的方法和属性,并且能实现多态以创建健壮的、扩展性好的组件。例如,假定你从基类 Crane里继承产生了一个ForkLift类,你能使用像下面的代码覆盖基类里对Lift方法的默认实现:
Public Class ForkLift Inherits Crane Overrides Sub Lift(ByRef _ Height As Double) Height = Height + 10 End Sub End Class |
VB.NET不仅能让你覆盖方法或属性;它还能让你重载方法。重载是定义同名、但使用不同数据类型的方法或属性的能力。例如,假定你有一个组件能对不同数据类型的数组进行排序,你不需要三个(每种数据类型一个)不同名的方法;实际上你可以重载一个方法名:
Overloads Sub SortArray(ByRef _ aValues()As String) ... Overloads Sub SortArray(ByRef _ aValues() As Integer) ... Overloads Sub SortArray(ByRef _ aValues() As Object) |
另一个改变是:表单现在是类模块。这就是说类本身包含建立表单的所有“肥料”的代码。你可能想知道,为什么你不得不看到这些从前不用看的代码,但这个改变同时带来强大的新功能,包括继承这些表单的能力。Microsoft把这一技术称为可视化继承。假定你的对话框有一种标准的格式,例如在表单的一侧有一行按钮,并在角上有一个标识,那么,通过可视化继承你能创建一个表单模板(类),并从这个基类里导出所需的表单。 一切都是对象
代码复用简化了开发过程,像实现和可视化继承这样的功能有利于更简单、更强大的代码复用。然而,代码复用并不是到此为止。你能通过支持VB.NET的通用语言运行库(Common Language Runtime - CLR)继承在其它 VS.NET 语言里定义的类。例如,你或别人创建了一个 C# 类,然后就能从 VB 里继承它。
VB.NET 的面向对象能力扩展了语言本身的通路:一切都是对象。这意味着比在以前的 VB 版本里,你获得了更多的内在功能,你将很少被迫使用 Windows API。例如,在以前的 VB 版本里,你使用 LoadPicture 方法加载图片并使用表单的 Line 方法(或较快的 API) 画线。现在,你使用 System.Drawing 对象来创建并处理图形。你可以使用以下代码在表单上显示一幅图片:
picshowpicture.Image = _ system.Drawing.Image.FromFile( _ "c:\test.bmp") |
注意 VB.NET 的“一切都是对象”方式让你的语句能用得更长久。
考虑以下语句,它在一个图形对象上画一条黄绿色的线:
objgraphics.DrawLine(system.Drawing. _ Pens.Chartreuse, 0, 0, 100, 100) |
这些长长的语句也有好处:改进的功能、适应性和易用性。从前,你要实现先进的功能就不得不在文档中挖掘,经常是不得不诉诸API。现在,相关的功能集符合逻辑地包含在对象里。这种处理方式的另外一个好处就是:类把相关的功能很好的组织了起来。所以,浏览你感兴趣的对象,发现它们做些什么实际上很有意思。
Visual Basic.NET 的面向对象功能提供了很多实在的好处。很多情况下,VB.NET 面向对象的本质和实现的继承性能帮助你比在以前的 VB 版本里更容易、更迅速地创建特定类型的功能。然而,你不一定要仅仅因为你能做到,就使用实现继承性或其它 .NET 功能。VB.NET 的新功能使开发许多类型的应用程序变得更简单!但是,就像使用所有的语言能力一样,你需要使用的是在特定场合下最适合的功能。
对于自由线程可能需要特别给出警告。VB6允许你使用独立的线程来创建多线程服务器程序,但VB过去从来没有让你能创建自由线程的客户端程序。VB.NET 改变了这一切。现在,创建自由线程应用程序几乎成了最微不足道的事情。实际上,我估计那些没有理解其中的微妙差别,就在他们的应用程序里添加了自由线程的程序员会遇到很多问题。只需要几行代码就能启动一个新线程:简单地将线索对象的地址传递给方法,方法本身就会启动线程。这确实是很酷也很有用的东西,但你需要小心:这些功能适用于特定的场合,确定哪些是适用的场合并且明智的使用这些工具则是你自己的事。许多开发者使用继承性和自由线程时给自己找了不少麻烦,请不要让这些发生在你身上。可能大家讨论得最多的 VB.NET 特征就是 CLR (通用语言运行库),VB 运行在它的顶层上。是 CLR 提供了 VB.NET 的许多关键功能。例如,CLR 使实现和跨语言继承性以及自由线程成为可能。
分发VB程序要求你同时分发VB的运行库,在VB6里即是msvbvm60.dll。许多其它语言也有类似的要求,包括 C++ 和 Java。在Visual Studio.NET里,所有的Visual Studio语言共享同一个运行库:CLR。这里有几个较大的变化,首先,所有的Visual Studio语言现在都共享同一个IDE、同样的表单引擎、同样的异常处理机制等等。这意味着Visual Basic和像 C#这样的语言拥有同等的地位,至少差不多是同等的。
易于反编译的中间语言
无论你用VB、C#或其它.NET语言编写应用程序,VS.NET代码都编译成为中间语言(IL)。当应用程序运行时,一个即时编译器(JITter)处理IL代码并把它编译成为机器语言。这意味着在理论上可能为Windows以外的平台创建.NET运行库,但现在关于类似的事情还没有任何官方消息。中间语言的一个缺陷是:它像VB5以前的VB版本一样,容易被反编译。这种可能性使许多开发者普遍地质疑.NET架构的安全性。
CLR在IL层次内外影响代码,对它的修改将使所有使用CLR的语言受益。然而,语言只是和代码如何被解释为IL有关,对特定语言的优化可以根据特定语言的语法来编写,这样在技术上就可能使.NET语言之间的性能差别很小。不管怎样,大体上蓝图是美好的。例如,CLR使VB的调试和监测工具和C#的相应工具相当,它做到了这一点因为它们本来就是相同的工具。
CLR提供不平行的跨语言集成,包括跨语言继承代码的能力。所有使用CLR的语言共享一个通用类型系统,它使使用多种语言开发应用程序变得更简单。我不喜欢把 C API 声明翻译成VB里可以使用的形式,所以我很赞赏通用类型系统带来的好处。在CLR中运行的代码被称为被管理代码,被管理代码使用的内存完全由CLR来控制。被管理代码带来很多好处,包括跨语言集成、跨语言异常处理和简化的部件相互作用模型。Visual Basic被限制为只能以被管理代码的方式工作,然而C#拥有跳到非被管理代码的能力(执行到运行库之外),并能做像指针操作这类事情。这是VB和C#不同等的情况之一。这种能力到底有多重要取决于你想干什么。
CLR造成的体系结构差别要比跨语言集成、共享功能和被管理代码等深刻。首先,Visual Studio.NET的支撑结构不是 COM。另外,VB.NET里的所有东西,甚至字符串都是对象。因为这些和其它一些原因,Microsoft改变了支撑结构处理对象的方式。COM实现了一个引用计数方案,这样每次引用一个对象时,计数器递增。当一个对象引用超出作用域或被释放时,计数器递减,当引用计数减少到零时就终止这个对象。Microsoft声称在.NET架构下引用计数的开销太大,以至于不能在 .NET中实现它,所以它放弃了引用计数转而使用垃圾收集。
垃圾收集需要新体系结构
CLR垃圾收集器主要是监视一个程序的资源,当可用资源达到确定的阈值时寻找无用的对象,并在发现它们的时候清除这些对象。垃圾收集的一大好处就是你不再需要担心大多数普通的循环引用,即子对象引用了父对象,然后父对象又引用了子对象。在引用计数方案下,循环引用使两个对象都不能被释放和清除。然而,垃圾收集器会发现循环引用并清除它们。这也意味着释放对象的最后一个引用时不再需要立即清除对象。
垃圾收集的一个后果是:你再也不能指望一个类的 Terminate 事件能在适当的时机发出。实际上,如果线程被阻塞,可能根本就不会发出 Terminate 事件。和COM提供的确定化终止相反,它被称为不确定的终止。缺乏确定化终止,以及因为垃圾收集器重新安排并压缩内存从而不能使用指针的事实,在新闻组里激发了一波激烈的辩论。我想这些新限制可能会令你痛恨,因为你要依靠确定化终止;也可能你漠不关心,因为你不依赖 Terminate 事件。垃圾收集并不是万灵药,实现弱引用依然需要做一些考虑。
从引用计数到垃圾收集只是 Visual Studio.NET 的支撑结构不是 COM 这个事实的表象之一。你能在VB.NET中使用COM对象,比如说ActiveX服务器或ActiveX控件。然而,你必须通过包装访问这些对象。任何时候听到“包装”这个术语,你应该明白你面对着性能损失,并且对象的行为可能有所不同。如果当计划移植一个使用了大量COM对象的工程,就需要认真地测试和计划,可能需要重新规划应用程序的结构才能移植成功。坦率地说,你要有遭受挫折的准备。还记得从VBX迁移到 OCX的过程吗?我记得,我的精神病医生也记得。我很快就要再去看他了。
语言本身的变化要远远超过体系结构的变化。大部分改变确有道理,但我并不认为所有的改变都是如此。以前版本的VB允许你以很多方法来做很多事,以至于统一的编码标准要么不存在要么就很难强加于人。Microsoft对VB做了大量的改变为的就是“清晰”这种语言。很多情况下,原来你有好几种方法做一件事,现在就只有一种了。Billy Hollis 提供了语法变化的详细列表,包括废弃的关键字列表,但有些东西需要在这里重复一下。
首先,向过程参数传递数据的默认方法由引用(ByRef)变成了传值(ByVal)。这个改变主要是因为引用要比传值的风险大得多。它的风险主要是调用过程中的数据可能被无意中篡改。你仍然能通过引用传递数据,但这一改变使你需要修改新的默认调用方法来使用引用。
其次,Set 语句消失了。在 VB.NET 里如果你需要向变量传递一个对象引用,所需要的只是一个等号,对象被视为同其它值一样。这很酷,但也有副作用:默认属性消失了。例如,你不再能用这种方式引用一个属性:
Text1 = "What, me worry?" |
作为替代,你必须显式地引用属性:
Text1.Text = "What, me worry?" |
也许一眼看来不需要这种改变,但确实必须去掉默认属性。例如,假定你有一个叫objFoo的对象变量,不用Set语句,下面的语句所设置的引用就产生了歧义性:
objFoo = Text1 |
这条语句是应该设置到Text1的引用,还是以Text1的Text属性来填充objFoo?你不能确定,编译器也不能。抛弃Set语句同时要求抛弃默认属性。有一个改变我不喜欢:你不再能在不同的作用域里声明Property Get和Property Set过程。注意 VB.NET 没有 Property Let 语句:对象和数值都用 Property Set。这意味着你不能用一个 Friend Property Let 过程来对应一个 Public Property Get。用VB建立组件时可能会有麻烦。许多组件开发者创建 Friend Property Set 过程以使他们的应用程序能改变一个值,但提供 Public Property Get 过程以使他们的客户程序能取回值。我希望我能为这个改变找到一个合适的理由,可是我找不到。
Microsoft说它力图使语言保持清晰并使之现代化—大部分情况下它做得不错—但这个作用域问题和其它几个问题令人感到困惑。例如,While...Wend 很早以前就应该消失了,因为 Do...Loop 完成同样的功能。然而,Microsoft 不仅没能去掉 While...Wend,还把它改成了 While...End While 来给自己找了更多的麻烦。真奇怪!
我最不喜欢的改变是:Microsoft改变了你已经使用的数据类型含义。在 .NET 里,Integer 现在是 32 位,而 Long 变成了 64 位。我心存恐惧地想:开发者 (包括我自己) 会多么频繁地使用错误的变量啊。那个API到底是接受一个16位的 Integer还是32位的?老天!我希望Microsoft重新考虑这个决定并使用新的变量类型,比如Int32和Long64。无论迁移到 VB.NET的移植工具是多么的好,它也不能改变开发者的记忆。为什么要逼着我们再学一遍普通的数据类型呢?
最后,最需要的一个改变是:VB.NET引入了 Option Strict 关键字,你可以使用它来代替 Option Explicit。Option Strict 结束了万恶的类型强制(tm),通过它VB乐于让你把一个数值赋值给一个字符串,然后像犯罪一样做另一个操作。设置 Option Strict 告诉 Visual Basic.NET 不要为你做任何类型强制。注意 VB.NET 并不是彻底的控制狂,它允许类型向下转换,但不允许向上。例如,不使用像 sngvariable = CSng(dblvariable) 这样的语句进行显式类型转换,你就不能把声明为 Single 的变量赋值给声明为 Double 的变量。因为这有丢失数据的风险。然而,你能不使用显式类型转换就把声明为 Double 的变量赋值给声明为 Single 的变量,因为这并没有丢失数据的危险。使用 Option Strict 能帮助开发者减少很多类型错误,包括那些很难调错的。但有一个附加的缺陷:在工程里使用了 Option Strict 后,就不能进行 后编联了。
表单和新IDE面孔
Visual Basic.NET 的面向对象功能很伟大,但第一次启动 VB.NET 时还注意不到它。可能你注意到的第一件事是它的 IDE。IDE看起来可能很熟悉,建立VS.NET IDE的团队以前的工作是开发VB的IDE,对IDE的增强借鉴了VB IDE的经验。
同时,IDE的改变远比外表显示的深刻。所有.NET语言使用相同的IDE,并且IDE中的新工具功能强大又易于理解。你能把任何一个设计窗口设置为自动隐藏 (就像你能自动隐藏Windows任务栏那样),这样就大大地减少了混乱。主工作区域是一系列选项卡,这意味着IDE不再同时显式多个表单和代码模块。当打开对象的源代码时,IDE在它的主工作区域为工作的对象添加一个新的选项卡。IDE还包括一个叫作任务表(Task List)的新窗口。它的内容由IDE创建的项目组成。例如,如果在试图编译一个工程时收到一个错误,VB在任务表里创建一个项目来解释这个错误。你能直接向任务表里添加项目,或者通过在代码里以 "TODO:"开始一个注释行,你可以在代码位置和任务之间建立联系。我喜欢Microsoft实现任务表的方式;在程序出炉前,都需要完成些什么?估计它能帮我省掉很多时间和麻烦。看到它时,你最容易产生的一个想法就是:以前怎么就没人想到它呢?
你能注意到的另一个变化就是:VB.NET的表单。Microsoft废弃了旧的表单引擎而使用Windows Form代替它。所有基于 CLR的语言都使用Windows Form引擎。相对于VB6的表单引擎,它有几个重要的改进。例如,Windows Form让你能创建能自动调整组件尺寸的表单,并允许将控件锚定在表单里的特定位置。换句话说,不再需要使用第三方控件就能完成这些特殊任务。Windows Form还允许表演像透明表单这样的很酷的技术。
过去,VB隐藏了建立表单的所有魔术。你使用IDE设计表单并把代码添加到Initialize事件上,但你没有手段来控制这两点之间的过程。现在,表单就是一个类,它包含用来建立表单所有的代码。我把这些代码称为肥料代码,因为大多数开发者希望远远离开它们,越远越好。要想可靠地弄坏你的程序,没有比折腾这些代码更好的办法了。另一方面,技术娴熟的用户可以通过这些代码做很多很酷的事,因为它让你能走到VB.NET表单的幕后。要是你不想看到这些代码你也能不看,因为新代码编辑器有展开和折叠代码区的功能,并且这些肥料代码是默认折叠的。代码编辑器还有几个很酷的新功能。例如,现在它自动为你缩排所有代码(而且还干得不错),它还有内置的显示行号功能。
创建编译的服务器端代码
除了新的Windows Form引擎,.NET还包括一个为创建Web表单而特别设计的表单引擎。这些被称为Web Form的表单很聪明,就像VB让你能很容易地为传统Windows桌面应用程序创建表单一样,它们让你能方便地为Web创建表单。Web Form是 ASP.NET里的技术,让你能使用熟悉的RAD工具创建带有代码的表单。创建的ASP.NET代码编译并驻留在服务器上,并在那里被执行,然后以HTML方式发送给任何一个支持HTML 3.2的浏览器。
底层结构捕获客户端上的事件数据,并把它发送给服务器。这意味着可以使用各种用户界面工具,可以利用现有的表单设计技巧,而且应用程序界面是不依赖浏览器的。如果可以放弃不依赖浏览器,你还有另一个选择来利用Internet Explorer 某些功能特有的优势。Web Form使支持Web的应用程序能更容易地创建更好、更丰富多彩的用户界面。 Web服务策略
VB.NET里的另外一个重要的面向Web的功能是:Web服务。Microsoft的市场部门把Web服务列为采用.NET的几大理由之一。实际上,Web服务的本质就是使用标准协议的、由Web服务器提供的、类似于COM的对象。注意在技术上它们并不是COM对象,但和COM对象的表现方式很相像。Microsoft希望看到所有的公司使用Web服务,并且未来的应用程序可以简单地“粘”在不同的Web服务上,就像现在可以使用Visual Basic for Applications (VBA)建立基于Office和支持VBA的程序的解决方案一样。
在PDC上,对于它希望开发者如何“粘”在这些服务上,Microsoft提供的一个演示程序给出了很好的例子。在这个演示程序里,一个假想的诊所通过Web服务提供预约系统,演示了你可以怎样使用智能电话通过Web进行预约。Visual Basic.NET 甚至会允许你查询服务器,并获得关于服务器能支持的所有Web服务的相关数据。通过IntelliSense dropdown这个绝对有用的工具,程序员可以访问Web服务。Web服务是Microsoft雄心勃勃的战略,但只有时间才能检验它是否能成功地被广泛接纳。
Microsoft试图消除与包装和分发应用程序相关的问题,包括令人恐惧的DLL。所有.NET应用程序被封装为元件。元件包含着数据以描述它运行所需的东西。这些数据被称为货单,包括很多信息,例如:元件身份(名称、版本等等);一个列出了所有文件之间的依赖关系的表,以及它们的位置和版本;包括DLL相关数据的外部依赖关系信息;还有其它元件需要而开发者没有创建的资源。元件是自说明的(通过它们的货单),所以.NET应用程序不需要修改注册表才能工作。换句话说,你不再需要注册表组件。在最好的情况下,即客户机里已经有了.NET运行库时,分发一个复杂的应用程序可能只是把一个文件夹复制到目标机器上这么简单的事。元件的另一个好处是:你可以让不同的应用程序使用同一个DLL的不同版本,并且协调地运行在一台机器上。如果所有这些都可以像计划中那样工作,有关DLL的地狱和版本的噩梦就将成为往事。
正确之路
Microsoft彻底更新了它的技术,而不仅仅是核心语言。例如,在Visual Studio.NET里同时提供了ADO.NET,这是有特殊优点的下一代ActiveX Data Objects (ADO) 版本。它的一个灵活改变是:ADO.NET用Extensible Markup Language (XML)作为在组件之间传递数据集的格式。这意味着接收组件不一定必须是ADO.NET组件,同时接收组件可以接受任何XML 格式的数据集。谈到XML,它支撑着VS.NET中的任何东西,从配置文件到远端过程调用。ADO.NET在处理断开的数据集时比 ADO的性能要好,并且具有更好的伸缩性。
Visual Basic.NET对我们都很熟悉的VB做了重要的改变。C++革命性地跳跃到.NET后有了一个新名字:C#,而Visual Basic的名字没变。然而,如果你把VB.NET当作语法相似的一门新语言而不是简单的“升级”,可能掌握起来就要容易一些。本文给你一个起点,但吸收掌握各种知识,并对未来做出有根据的决定是一个艰苦的过程,它只是这个过程的一条起跑线。我不知道.NET会有多么成功,它的很多地方吸引我,但有些地方并非如此。这个工具做了大量承诺,它夸耀很多功能能使 VB开发者更简单地创建更有伸缩性的高端应用程序。最后,它的成功将取决于开发者能多好地将它应用于现实世界。纵观Microsoft在PDC和Beta 1版本之间的性能和稳定性上所跨过的这一步,我坚定地认为:Microsoft走对了路!
如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。
现场直击|2021世界人工智能大会
直击5G创新地带,就在2021MWC上海
5G已至 转型当时——服务提供商如何把握转型的绝佳时机
寻找自己的Flag
华为开发者大会2020(Cloud)- 科技行者