细说VB.NET(中)
2024-07-21 02:21:07
供稿:网友
细说vb.net(中)
(作者:青苹果工作室编译 2001年03月07日 14:47)
易于反编译的中间语言
无论你用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语句消失了
其次,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 后,就不能进行 后编联了。
<<<<<上一页:概要、vb获得了继承能力、一切都是对象、自由线程的危险
>>>>>下一页:表单和新ide面孔、创建编译的服务器端代码、正确之路