最近公司要开发Windows平台上的产品(由于涉及到商业机密,所以目前无法对这个产品做详细介绍),采用.Net技术进行开发,我负责的是基于Visual Studio插件机制的行业开发工具的开发。从开始接触.Net到现在已经有近三个月了,而且也开发出了第一个版本,对.Net已经有了一些认识,由于以前主要用Java、Python等语言进行开发,因此有意无意的就对这些语言进行了比较。和Java比起来,.Net的优势还是很多的,比如快速开发能力、基于Windows特性进行开发的能力、内置的丰富类库、一些高级语法、组件的多版本管理等。优点是不用过多夸耀的,缺点我则要好好的“批评”一番的,因为“谦虚使人进步,骄傲使人落后”嘛,呵呵。开发场景为:使用Visual Studio2005进行C#的开发、使用Eclipse进行Java开发。 
 
1、HotSwap:在Java中HotSwap技术给程序的调试带来非常大的方便,比如可以让程序一边调试一边修改代码,代码修改以后在程序中立即就可以看到修改后的效果,不用每次修改以后都要重新启动程序;在.Net中几乎不允许这样做,只有在非常苛刻的几个情况下才可以实现在调试状态下修改代码,而且一旦代码段被执行过了就肯定不允许再修改了,这就导致每次修改代码都要频繁启动程序,非常繁琐。
 2、基于.Net的东西和Windows结合过于紧密,而且和Windows平台下一些旧有技术有太多千丝万缕的联系,导致用起来非常麻烦。比如每个对外部系统暴露的接口传来传去最后看到的类型是_ComObject,要想得知其真正的接口类型就必须通过COM技术来取得,非常麻烦;开发的很多组件都需要到注册表中注册,增加了部署的难度。

3、Visual Studio中代码的即时查错能力非常弱,很多的要到编译时才能知道代码是否有错;而在Eclipse中在编写代码的时候对于有错误的代码和有警告的代码(比如一些Private成员没有被引用)可以立即清晰的提示出来,开发人员可以立即修改有错误的代码。



4、Java中默认的方法都是可以override的除非标注为final,而在C#中必须是明确声明virtual的才可以override。在Delphi中也是类似的问题,这应该是Delphi和C#共同的老爹Anders Hejlsberg对于OO的一种理念吧,也许人家大师的想法是正确的:一个方法是否是虚方法必须要明确指定。不过对于习惯了Java中这种实现方式的人来说,C#的这种实现方式还是让人感觉一时难以适应的。



5、Visual Studio的编译速度太慢,点击【调试】/【运行】按钮以后要编译好长一段时间才能启动(不过和Visual Studio6比起来现在的Visual Studio编译速度已经快多了了,已经接近于Delphi的编译速度了);由于Eclipse使用的自己的高性能编译器Eclipse Compiler,而且代码的编译是在编写代码的时候即时进行的,所以在Eclipse中根本感觉不到编译的时间,点击【调试】/【运行】按钮以后程序就运行起来的。



6、.Net类库中一些类设计的不灵活,比如TreeView的节点的显示的值是通过Text属性赋值上去的;而在Java中的Swing、SWT等图形库中,可以在一个树节点中挂任何类型的值,然后通过为这个节点定义个性化的Render(渲染器)来决定这些树节点显示什么。



7、Visual Studio的插件体系过于死板,开发起来不像开发Eclipse插件那样灵活简便,这可能和Visual Studio插件体系的历史渊源有关系。举例如下:
(1)比如要在代码编辑器上增加新特性,在Eclipse中可以通过代码编辑器中提供的大量扩展点来实现,而在Visual Studio中的代码编辑器中则只提供了很可怜的几个可扩展性。这一点是Visual Studio插件体系最大的硬伤,大大限制了基于Visual Stuio的插件的功能,相信随着MS对Visual Studio插件体系的逐渐重视,这一点会慢慢跟上来的。
(2)Visual Studio的插件体系和.Net结合过于紧密,在Eclipse中可以为Python、Ruby、C#、C、ASM等很多语言开发IDE(提供代码编辑、代码辅助、调试、编译等功能),这些语言不必与Java有任何关系,而在Visual Studio中虽然也可以为一种语言编写IDE,比如IronPython、J#,但是这些语言是和.Net集合紧密的,比如要为这种语言提供调试功能,则必须将代码编译成MSIL代码,这对于很多语言来讲是不可能的;
(3)Eclipse中的插件只要在自己的plugin.xml文件中配置好就可以了,把那个插件的jar包放到Eclipse中就可以运行,而Visual Studio中的插件则必须首先注册到注册表,调试和部署起来非常麻烦;
(4)Eclipse运行时的配置是保存在Workspace中的.metedata目录下的,因此在开发插件的时候会把插件的配置信息自动写到Host起来的那个Eclipse的Workspace中,被调试模式启动的Eclipse所做的一些修改不会影响主Eclipse,而在Visual Studio中虽然可以使用Experimental Hive方式进行插件开发,但是由于这些配置是保存在注册表中的,所以被Host启动的Visual Studio实例会污染到主Visual Studio,每次重启IDE都需要运行“Reset the Microsoft Visual Studio 2008 Experimental hive”来进行环境的重置,且重置耗时非常长,浪费了大量时间;
(5)VS2008中,如果插件中抛出异常,而又没有捕获的话,轻则VS2008会显示一个错误消息框,重则VS2008会宕掉;而在Eclipse中会将插件中未捕获异常显示出来并且输出到日志文件中,方便插件开发者排查插件的Bug。
(6)Eclipse中工程相关的特性是以Nature的方式提供的,一个Nature通常可以挂接到几乎所有的工程类型中去,包括用户自定义类型;而在Visual Studio中工程相关的特性则是以SubProject的形式提供的,往往只能挂到Visual Studio内置的少数几个工程类型中去(比如CSharpProject、VBProject),这样可扩展性大大降低了。
(7)Eclipse中可以使用JET来开发非常复杂的代码生成器,而Visual Studio中的代码生成则只能用非常简单的代码模板机制,复杂的逻辑就必须通过字符串拼接来完成;



        毕竟接触.Net时间还是非常短,所以有的地方说的可能有错误,还请园子里的兄弟多指教。最后祝.Net和Java能在相互竞争中快速成长,从而让我们开发人员能够轻松、快乐、快速的开发出产品来,:)