摘要:为什么Borland创建VCL for .NET?什么时候你该使用VCL for .NET而不是.NET系统本身的的Windows Forms框架?
Delphi 8 for .NET在Delphi社群中引起了极大的关注!人们在新闻组,聊天室,以及用户们的小型聚会中频繁地谈论.NET基础架构,谈论它与我们都熟悉的Win32平台的关系。
其中一个热点话题是Delphi8的VCL for .NET。大部分争论似乎都集中在这个问题上:在这个宏大的规划中,VCL for .NET的目的是什么?它是一个短期的移植桥梁还是一个长期的应用框架。为什么Borland要创建这些东西来和微软的WinForms竞争?这是明智之举还是缺乏谨慎?
安静一下吧,没有必要再为这个问题争论不休了,真的。原因如下。
背景
微软的.NET框架提供了一个硬件中立的执行环境和语言无关的类型系统。这很好,但是要产生基于Windows操作系统的客户端应用程序还不够。.NET还包括了Windows窗体("WinForms")应用框架来为WIN32操作系统创建图形界面应用程序。熟悉在Delphi或C++Builder中的 Borland VCL应用程序架构的程序员们将会在.NET的WinForms框架中找到许多曾经相识的设计模式。这并不很奇怪:就像Anders Hejlsberg所说的那样,“是好机制那为何不用呢”。
虽然VCL与WinForms之间有很多相似之处,但实质上要移植现有的Win32 VCL应用程序到WinForms上是非常困难的,也是很痛苦的。而且这将限制采纳新的思路。相应的(软件)工具的销售也会带来同样的问题。
.NET是一个新的平台。在软件行业中,甚至所有新的活动都基于.NET,相对于现存的和正在进行的Win32开发而言,.NET应用程序开发仍只是很小的一部分。我们早些时候关于客户对于.NET平台兴趣的调查,非常清楚地表明,许多Borland客户对于.NET是一种不确定的兴趣,他们承担不起放弃在Win32平台上的所有投资的代价,而完全在新的.NET平台上从头开始。今天仍然如此,而且这种情形还将持续多年。
在Delphi 8 for .NET中创建一个WinForms是轻而易举的。现有的Delphi开发者们告诉我们:“这很好,但是我们能用它来为我们的VCL代码做什么呢?这些代码都是以前创建的,我们的业务都依赖于这些代码。”
为了让我们的客户更加满意,并且让.NET平台对于现有的Delphi开发者来说更加有吸引力,需要有一些东西来填补现存的Win32开发与新的.NET开发之间的鸿沟。它需要像.NET框架本身一样是一个纯粹的.NET,它还需要提供一个与现有Win32 VCL结构之间的高度兼容性。为了吸引现有的VCL开发者, Delphi for .NET需要的是一个在.NET平台上的实现的VCL。
我们首先考虑了在WinForms框架的之上实现VCL。在一些初步研究之后,事情变得很清楚,使得移植VCL应用程序到WinForms上很困难的架构差异,同样也使得很难在WinForms框架之上再建造一个VCL层,并且按照VCL的方式工作。
在我们评估WinForms的过程中,我们注意到WinForms其实是建立在Win32 API调用之上的。WinForms 窗口类调用CreateWindow()创建Wind32窗口句柄,它们勾住Win32的WndProc函数来侦听窗口消息,并且在类中触发相应的事件,等等,等等。
它们的工作原理就像VCL一样
如果在被托管的.NET代码中进行Win32 API调用对.NET框架适用,那么它对VCL也同样适用。这样,在.NET平台上实现VCL的过程就变成了找出如何进行Win32 API调用的方法,这是现存的VCL架构所依赖的,同时在我们可管理的范围内,又要对VCL自身代码的修改最少。
VCL for .NET的情况
VCL架构是与微软的WinForms架构对等的,而VCL for .NET是VCL架构的继续与演进。WinForms与VCL for .NET都建立在对Win32 API的调用之上,所以有相似的平台约束与相似的执行特征。对于VCL而言,甚至还有潜在的机会能比WinForms运行得更出色,这是因为VCL实现了针对笔,刷子,以及设备上下文的句柄共享,而WinForms没有。微调与探索这些性能方面的机会是Delphi开发小组持续的任务,就像微调WinFrorms的性能与.NET的性能是微软持续的任务一样。
VCL已经被证明可以适应于平台的变化—从16位Windows到32位的Win95,从NT到在Linux上基于QT的CLX。WinForms与.NET紧紧地捆绑在一起,而且在很大程度上与Win32捆绑在一起。
说明: 虽然.NET精简框架实现了WinForms命名空间中的许多类,在CF上还是有许多东西是不同的或者简单地缺失了。我不认为CF WinForm与Win32 WinForms在任何有意义的程度上是兼容的。微软显然承认这一点,因为他们让.NET CF执行环境与Win32 .NET的执行程序在二进制级别上就不兼容。.NET CF系统的assembly是强命名的,使用的是与Win32 .NET系统的assembly不同的关键字,这样,Win32 .NET执行程序将会在CF设备上装载失败。唯一的进入.NET CF的方法是把源代码在CF上重新编译,并且与CF的assembly链接起来。
对于应用程序代码来说,从Win32 VCL移植到VCL for .NET是相当简单的,但对于那些与Win32 API的关系更加紧密的组件来说,将可能需要更多的一点工作。这与移植到CLX的情况很相似。然而,Delphi开发者会发现,从Win32 VCL移植到VCL for .NET所需的努力要比从Win32 VCL移植到CLX所需的努力要少。VCL for .NET在很大程度上改变了执行环境,但实现了与Win32 VCL几乎相似的消息处理,异常处理,以及Win32 API支持。而CLX为了在Linux平台上运行不得不牺牲消息处理与Win32 API支持。
VCL for .NET的代码移植并不是单向的。为VCL for .NET 编写的应用程序代码也能在一个合理的范围内反过来被移植到Win32 VCL上。再一次地,要维护跨平台的同一份源代码,那些离Win32调用很近的操作代码(如定制控件),要比用常规Delphi语法编写的应用程序业务逻辑,会更困难一些。(常规的意思是避免不确定的类型转换与指针运算。)
用C#来编写应用程序就要让开发者们完全抛弃他们现有的代码与开发经验,在.NET中从头学起。C#把开发者完全限定在锁定的.NET平台上。在其它平台上并没有C#的实现。(是的,在Linux上有Mono,但它并没有实现UI/WinForms支持,因此它并不是一个完全的客户端应用程序开发的解决方案。)VB.NET几乎处于同样的境地,因为VB.NET用户痛苦地抱怨VB.NET与VB连基本语法都不兼容,这使得在VB.NET与VB之间移植代码比完全重写还要冒风险。
用Delphi语言为.NET平台编写程序还提供了将代码移植到其他非.NET平台(Windows与Linux)上的机会。用VCL for .NET来编写应用程序提供了任何其他.NET语言都没有的移植选项。
VCL for .NET是为Delphi程序员而存在的
VCL结构依赖于Delphi语言的几种强劲特性,这几种特性在其他.NET语言(包括C#)中一般都是没有的。然而,我并不期望C#或者VB程序员对VCL for .NET有浓厚兴趣。C#代码可以利用VCL for .NET组件,但VCL的某些方面(比如虚拟构造器)在C#中将是不显著且难以使用的。
用VCL for .NET实现的GUI控件只有Delphi程序员感兴趣,C#或VB.NET程序员都没有多大兴趣。
只要Delphi开发者保持这样一种观念,即某些独特的Delphi语法,并不能被C#或者其它.NET程序员很好地理解的话,如虚拟类方法,虚拟构造器,集合,标准化字符串,以及类引用,那么非可视组件,工具类,业务逻辑都能用Delphi实现并且被C#或VB.NET程序员方便地使用,
在VCL for .NET窗体上能放置WinForms控件。Delphi开发者编写的VCL for .NET应用程序