7C00.ME/houmu 2012-05-18

c#

前段时间某老师布置了一个程序设计作业,语言不限。我这阵子在搞Java,所以首先想到的是用Java。

按照我的习惯,在正式开始编程之前先要分析一下可能用到的技术,然后自己写自己例子test一下。

对于这个作业,我首先想到了GUI(不知道算不算是一个“通病”,包括我在内的很多学生在写程序的时候界面都会被放到很高的高度),然后去查。Java里面的GUI解决方案,主要就AWT,Swing还有SWT。AWT过于简陋,提供的控件种类太少;Swing基于AWT,控件丰富了很多,但是控件的外观却相当丑陋;SWT不错,功能很丰富,通过JNI调用操作系统原生的GUI控件,保证了主题风格和系统一直,但是网上评论,SWT存在效率、资源释放等问题。最后,权衡了一下还是用Swing,主要原因是相对于SWT,网上的关于Swing的文档更多一些。找了写文档看了看,主要问题是布局上的,Swing的布局功能实在是不敢恭维。最后,只有做了个妥协,把界面设计的简单了一些,对布局的要求就低了一些。

解决GUI选择问题之后,才想到功能的实现,这才发现问题来了。为了实现老师要求的功能,必须调用若干个Win32 API,当然有些功能可以通过Windows提供的一些系统命令实现,比如用reg命令可以完成注册表的一些操作,不用调用API,但是效率低了太多,也有很大的局限性,实现起来也不够灵活。Java里面调用Win32 API不是无解的,用JNI可以,用JNA(这时后来偶然发现的)也可以,对于某些API已经有人做好了封装。但是后来想想,自己用JNI实现,就要从头学起JNI,以前也就只有知道这么回事,还有Win32 API的调用也要单写一个dll出来,相关学习和测试要花不小的代价;JNA不用写dll了,不过它的问题是文档太少了,特别是中文文档,也就是说现在研究这个的人不多,遇到问题也不知道问谁。

想来,当时自己一时冲动,决定用Java来完成这个作业,有些昏头了,有些找虐了。虽然,用Java完全是可以完成这个作业的,但是为此付出的代价(对于我)也是不小的。最后还是放弃了用Java,说好要在这段时间专注Java的,看来客观条件不允许啊。就用C#吧!于是,又见C#!

在上面的技术选择的过程中犯了几个错误,其一,界面实现不应该这么看重,初学开发的人或许都急于证明自己,所以喜欢学习做出“可见”和“可用”(交互)的应用,于是对于数据结构和算法、数据库等这类课程都不感冒,现在只能说“年少无知”啊;其二,应该看重的是功能的实现,这样就会想到Win32 API在这次作业中的重要性,C#对Win32 API的支持非常良好,很多函数都做了封装,即使没有封装的函数也可以自己用P/Invoke的方式调用,Java显然不具有这方面的优势;其三,不要对语言那么敏感,既然用的来C#,自己何苦为难自己,偏偏用Java呢,只能说自己有时候有些“一根筋”。

从Java转到C#意味着,我之前看的Swing的那些东西暂时没有用武之地了。不过Java和C#本身的相似性,也让我在程序类图、流程设计上(做软件工程课程设计带来的不自觉的习惯,这么小一个程序,还要弄这种东西,习惯害死人),迁移还是很方便的。Java的Swing中,JTable使用TableModel的子类来管理数据,通过某一接口访问这个子类,需要更新UI的类实现这个接口即可。C#的GUI方案,我选择了WPF,用的是DataGrid。DataGrid有个属性是ItemSource,如果设计一个接口来管理这个属性,需要更新UI显示的类实现这个接口就可以了,实际上,WPF本身的数据绑定的特性,在数据显示更新上省去了很多麻烦的工作。

C#主要两套GUI方案,Windows Form和WPF。我选择了WPF,主要是在Silverlight方面做过开发,WPF的文档相对不多,但是Silverlight的倒是不少,两者的关系我就不多说了。对于我这个小应用,看Silverlight做GUI完全够用了,不同的地方自己注意下就可以了。昨天晚上,从硬盘的某个深处调出了尘封已久的一本Silverlight的pdf,随便浏览了一下。前面的介绍基本控件使用的章节,完全没有兴趣了。对于后面一些高级使用特性,让我有所思考。在最初学习Silverlight的时候,我可能就只会看前面的章节,因为,不管是用什么方法,利用这些章节的内容,基本上可以做出我想要的“样子”。而实际上,有价值的东西都是在后面,Silverlight的高级特性,使用效果上不说,单是其设计模式上都有值得研究的地方,比如灵活性和可拓展性。我以前一直就停留在用的层面,比如在属性面板里面,切换到“事件”选项卡,双击“事件”的名字,在cs文件里面自动就生成了一个方法,实现这个方法,就是对这个事件有了一个响应,姑且称之为回调吧,其他的我就不多想了。WPF里面回调的实质是什么呢?应该是“委托”,类似于“函数指针”。而在Java里面,比如Swing和Android的回调使用接口来实现的。二者其实就是两种设计风格,当然更多的细节,我还是不清楚。

个人感觉,微软为C#提供了一个强大的IDE,Visual Studio,拖拖拽拽就完成了开发,所以有些人读C#颇为不屑。不过C#从2000年发布以来,一直在增加新的特性,语言的功能越来越强大,只不过很多高级特性,有些人没有意识到去用;C#已经4.0(不算Windows 8和.Net 4.5)了,不过很多时候使用的水平还是在2.0左右。罢了,就扯这些了。(文章里面尽量回避语言之争,如果不小心涉及到了,请忽略。)