JAVA程序员看C#的精华与糟粕

来源:互联网 发布:育知同创和千锋哪个好 编辑:程序博客网 时间:2024/04/27 21:46

C#和java是号称90%的相同加上10%的不同。因此当时我学习C#,阅读两种代码完全没有什么阻碍。

对C#了解得深入以后,来发表下对这两种语言各自特性的一些看法.

比较起java和C#大相径庭的那10%,会发现C#五花八门的特性要多很多。比较知名的有:委托,属性,真正的泛型,索引器,类初始化器,分部类,操作符重载,struct,unsafe代码,IDisposable等,另外.net framework 3.5还加了一大串纯粹由编译器提供的特性。

委托,这个可以算是C#之于java的最大优势。虽然java可以依靠接口,匿名内部类这些特性实现委托一样的功能,但却要麻烦许多,如果涉及到N个委托实例相加的情况,那么一个C#里面简单的"+"号,在java里就只能用FilterChain,InterceptorStack这种概念了。

属性,据说属性信息是带到运行时的,后查看反射的确有PropertyInfo类,之前说它是编译器语法糖是受了某篇分析IL代码的文章误导,不过这个是不是语法糖都没什么关系,它和java普遍做法的get,set各有优劣。属性写起来简捷,但却比较难看出哪些属性是只读,哪些是只写不读。

真正的泛型,这个又是一大C#的优势,同时伪泛型又是java的一大败笔。但是java年代比较长,为兼容性考虑不得不使用假的泛型实现。如果泛型不是在jdk1.5时推出,而是在jdk1.4,和collection framework一起推出,我认为它也会采用真正的泛型实现。

索引器,有了这个很多容器类都可以直接用[]取元素,感觉还不错,比没有好,编译器的小把戏。

类初始化器,典型的懒汉特性。每次用顶多能省下一两行代码,又是编译器的小把戏。

分部类(partial class),纯粹为了vs.net的那一大堆图形化设计器老和人的代码冲突而搞出来得玩意,又是编译器的小把戏。

操作符重载,属于用到得不多,要用时却显得特别有用的东西,很奇怪java为什么不提供这个功能。

struct,在堆栈上的东西,释放内存那是超级的快,只不过需要用到这个的场合,大概都在使用C++编程。

unsafe代码,纯粹增加语言复杂性的东西。就好像一个人搬家,看这个不舍得扔,那个也不舍得扔,搞到最后把瓶瓶罐罐都搬走了。

IDisposable,实现这个接口,配合using块,非常的强大,终于可以像C++那样掌握对象的销毁了。

接着说说java比C#多的特性:

匿名内部类:真是极端方便的一个东西,还和JAVA的好多设计模式有关系,不过C#把java匿名内部类的写法拿去用作类初始化器了,糟蹋了...

动态代理: java里面要实现AOP,易如反掌;C#要实现AOP,难如登天,不得不借助Assamble命名空间下的那些动态IL生成工具。这就是动态代理的作用。

希望有一天C#可以拥有匿名内部类和动态代理,变得更完善。也希望java也可以有委托等。

复制代码
  1. 委托,属性,真正的泛型,索引器,类初始化器,分部类,操作符重载,struct,unsafe代码,IDisposable等
  2. ----------------
  3. 大哥,这些叫“花里胡哨”吗?
复制代码
  1. 难得有人比较Java/C#,俺是Java门外汉,看到后有了不少新认识。
  2. 1)个人觉得,Anders 想用C#代替Windows上C++王者地位,正如楼主所言,有unsafe等关键字。但远不止这个,它还有被Dijkstra批评了几十年的著名的goto语句!真有点不可思议!
  3. 2)关于struct,不同意楼主的描述。struct是值类型,在栈上分配空间,比堆上分配和管理效率高。特别是增加泛型后,可以省略box、unbox等操作,使用struct显然自然和高效。
  4. 3)关于属性。这个东西是Anders在Delphi中借鉴过来的,估计有十五年以上的历史了,对于OOP编程的确很方便,应该算作语言特性吧。
  5. 上面拙见不一定正确。无论如何,天才的Anders也有想得不周到或受到限制的地方,完美的语言恐怕有,但肯定不实用!

 

复制代码
  1. C++ 按楼主的理解 就是不堪的语言了。
  2. 个人认为C# 保留大部分老语言的特性是很明智的。
复制代码
  1. 恕我直言,好多花里胡哨的东西在C#里面是必不可少的,没有了确实很不方便
复制代码
  1. 呵呵,其实楼主本人在首页放这种贴子就是想挑战一下大家的水平,不过你的贴子所包含的技术含量太低了,楼主在贴子中到处用到了编译器的小把戏,其实这也是java的败笔,sun本身就是一个校办工厂出身,所以做出来的东西学术气氛很足,Anders本身就是一个实用派的代表,看看他以前的作品就能知其一二了,如果有机会楼主同c#程序员用java和C#同时做一项目你就知道java的学术气息了.
复制代码
  1. unsafe代码,纯粹增加语言复杂性的东西。就好像一个人搬家,看这个不舍得扔,那个也不舍得扔,搞到最后把瓶瓶罐罐都搬走了。
  2. ----------
  3. 这个比较形象。。。。。。
复制代码
  1. 不太同意楼主,正是“编译器的小把戏”才让我们使用那么方便!
复制代码
  1. 就好像一个人搬家,看这个不舍得扔,那个也不舍得扔,搞到最后把瓶瓶罐罐都搬走了。
复制代码
  1. 1)个人觉得,Anders 想用C#代替Windows上C++王者地位,正如楼主所言,有unsafe等关键字。但远不止这个,它还有被Dijkstra批评了几十年的著名的goto语句!真有点不可思议!
  2. 请仔细的看看Dijkstra人家的原话,人家从来都只是说要慎用,没有说要取消,那c#里有goto关键字又如何呢?
复制代码
  1. 属性,其实不是语言特性,只是编译器的功能,这个和java普遍做法的get,set各有优劣。属性写起来简捷,但却比较难看出哪些属性是只读,哪些是只写不读。
  2. ------------------------------------------------------
  3. 呵呵, 楼主, 您了解C#多久了?
  4. 太误人子弟了!
复制代码
  1. 恩 IDisposable仅仅是一个名称上的约束,主要是用来对于非托管资源的释放,至于托管的资源(内存),还是GC来做的,它不能象C++那样子严格的控制对象的生命周期的。java也是一样...... Linq lambda 这东西lz应该说说的......
复制代码
  1. 还真找到[url]http://en.wikipedia.org/wiki/Edsger_W._Dijkstra[/url]上介绍Dijkstra的文章。从其论文看,的确是against语句goto,并认为是harmful。下面是其中的一段话。
  2. He was also known for his low opinion of the GOTO statement in computer programming, writing a paper in 1965, and culminating in the 1968 article "A Case against the GO TO Statement" (EWD215), regarded as a major step towards the widespread deprecation of the GOTO statement and its effective replacement by structured control constructs, such as the while loop. This methodology was also called structured programming, the title of his 1972 book, coauthored with C.A.R. Hoare and Ole-Johan Dahl. The March 1968 ACM letter's famous title, "Go To Statement Considered Harmful", [1] was not the work of Dijkstra, but of Niklaus Wirth, then editor of Communications of the ACM. Dijkstra was known to be a fan of ALGOL 60, and worked on the team that implemented the first compiler for that language. Dijkstra and Jaap Zonneveld, who collaborated on the compiler, agreed not to shave until the project was completed.
复制代码
  1. 1. 属性不是“编译器”的小把戏,其信息是要进入元数据的;类似的还有事件。
  2. 2. goto语句的最大用途就是在反向工程中;如果一个项目进行了简单的混淆(类似于花指令那种),可以通过goto得到可以编译的源代码。
复制代码
  1. 从语言特性来看,java是C#的子集,毕竟C#是吸收了java和其他很多编程语言的优点而被“发明”出来的。“花里胡哨”?“匿名类”?“动态代理”?还是对.net多些了解再发表意见吧!
  2. 诸如泛型、partial class/function、LINQ等等新特性,正是因为C#已经不仅仅满足功能的完备,而是开始追求编程语言本身的优雅、高效和敏捷性。比如将查询集成到编程语言的LINQ,绝对是编程语言发展的新境界,其他语言只是还没有来得及跟风而已。如果把这些简单概括为“编译器的小把戏”,未免狂妄。
复制代码
  1. 诸如泛型、partial class/function、LINQ等等新特性,正是因为C#已经不仅仅满足功能的完备,而是开始追求编程语言本身的优雅、高效和敏捷性。
  2. --------------------------------------------------------
  3. 感觉这句话还是比较有道理,现在的C#已经是一门相当完备的语言了,所以的确可以追求一些更方便的特性。
  4. 不过我的确非常喜欢java里的匿名类,那要比C# 3.5里的匿名类强大很多,因为那个匿名类是可以实现接口或者抽象类的,很多设计模式在java上的实现也的确是围绕匿名类展开的。
  5. 动态代理这东西我也是听说过没用过,毕竟java用的少,但是据我所知Hibernate正是利用了这一特性实现了属性的延迟加载,这一个功能目前在NHibernate上还是只能靠编写代理类来实现哦。
  6. 不得不承认java相比C#有其独到的优势——平台优势就是最明显的一点,基于java,可以做到除了硬件什么都不花钱的平台搭设,而这一点.NET平台就很难做到了。而且java EE方案经过数载沉淀,体系完整、架构成熟、资料齐全、人才丰富,这些是.NET平台暂时还比较缺乏的。
  7. C#很大的优势在于它是一门新兴语言,拥有很多新的特性,充满活力,MS利用大量编译时技术为C#带来了众多的便利,这使得C#成为一门“入门很容易,精进空间深”的语言,我觉得也是非常有前途的。但是目前在企业级平台上.NET估计还是很难干过JAVA EE
复制代码
  1. partial在写大类型的内部类时,可以将内部类给剥离到另一个cs文件。
  2. 属性不是语法糖,VB的属性甚至支持传参。属性与事件一样,可以在接口定义,具备独立的元数据,并且可以针对属性设置Attribute(而不是getter或者setter)。
  3. 话说回来,C#的所谓的那些语法糖,又有哪个不是缺少了挺难受的,迭代器语法、匿名方法、匿名类型……
复制代码
  1. 楼主写得很好,C#1.0其实已经很完美了,后面那些花里胡哨的功能,其实都是些"小玩意儿".(泛型除外,倒不是因为泛型很方便,而是泛型效率高些).
  2. 优秀的代码是一种习惯和修养,C#越来越走火入魔了,太多非"本质"的特征,只是为了少写点代码而已.
复制代码
  1. 我用过(这里的用过不是刚毕业小孩子说的那种“精通”)Delphi、Python、Java、.net、C/C++,只能说.net是一个大垃圾。要不是项目需要我打死也不会用这破玩意,不支持真正的AOP、不支持真正的HotSwap、不支持真正的HotDeploy、一堆Bug。。。垃圾垃圾
复制代码
  1. @CowNew开源团队我不敢说java不“支持”AOP,但是我敢说java对AOP的“支持”都是靠人编程编出来的吧。什么语言天生支持AOP??我承认我对AOP了解甚微,但不否认AOP是个概念,有准确的定义吗?任何一篇文章,能准确的阐述AOP的定义吗?能准确的规定什么叫“支持”AOP的语言吗? @garbage==w3c 支持我的原则就是,当没方便可寻的时候,或者寻方便的代价>方便的优势的时候,就不去寻方便啊。但如果寻方便根本不需要代价,或者代价小于获取的收益,那既然是赚的事情为什么不去做呢?做2拿3和做3拿3或者做2拿2,我相信谁都知道到底是哪个选择更“值”一点。
复制代码
  1. 早上发了贴,中午回来看,这么多回复了。看来这类枪战文确实是blog大坑。
  2. 本人绝对没有偏袒java的意思,我早在java之前就接触了.net 1.1。只是java是我吃饭的语言。
  3. C#的编译器做了很多事,是好事,只是某一些特性,可能是令C#的惯用法显得很不同,却实际上只是方便了那么一点点,就比如.net3.5的表达式方法,虽然确实省下了一些方法定义,但是代码就显得迥然不同了。
  4. 另外特性多也增加了学习和记忆的负担。
  5. 可能有的人说,你记不住,你可以不用这些特性,用最原始的方法。的确C#设计哲学也是如此。但我们作为程序员,更多时候是要阅读代码。如果我们对各种特性不了解,那么就看不懂别人写的代码。所以这些名目繁多的特性,作为一个C#开发者,其实必须都知道。
复制代码
  1. 在我看来,只要一个语言特别合适干某一方面的事,它就很成功。
  2. 更何况,web开发部分,一直是java在潜移默化的影响C#。很多概念都是java中开始风行,然后C#界才开始听说这个东西,然后M$出相关的类库,然后被C#程序员所接受,比如orm框架,hibernate出来N年了,C#终于才出来linq2sql,比如依赖注入,现在EJB3用一个标签就能搞定组件创建和依赖关系,而C#的service如要使用DAO组件,恐怕还得自己写Factory或者单例吧。
  3. LZ这样的话就未免贻笑大方了。
  4. 首先Java在企业级软件上的成功,恐怕更多的是依赖平台和硬件的吧。不可否认,在Windows平台上,Java的市场份额已经……。
  5. 其次,那些所谓的风行的概念,在我看来不过是Java社区喜欢口水罢了。尤其在Web开发领域,JSP与ASP.NET两者现在已经不是一个级别的东西了。那个控件模型总不至于是C#阵营抄Java的吧。
  6. 再来谈LINQ,如果你了解LINQ就会知道这是一个与ORM完全背道而驰的思想。将其与Hibernate放在一起实在是非常无知的言论。ORM的核心思想在于Mapping,从对象映射到关系,而实际上对象根本就不等于关系,所以整出了这么个不伦不类的实体类到关系的框架还非要嘴硬说这是ORM。而LINQ完全是反其道而行之,将关系运算(查询)映射到面向对象的世界。从Hibernate推导出LINQ实在是。
  7. LZ不妨静下心来仔细品味.NET Framework,就会发现Java社区里面那些口水早就被.NET默默无闻的实现了。
  8. 就拿IoC来说吧,Attribute可是C#的发明吧。.NET Framework中的Plugin、Module架构难道还少了?楼主还好意思说Web,ASP.NET的原始架构就是IoC的。再来说说AOP,.NET Framework 1.1里面就有了CAS,不明白的自己翻翻CAS的资料,看看这个东西是不是注入函数的。
  9. 不要以为C#也像某些阵营的某些人那样,什么东西都要拿出来口水和哈拉,有时间还是写写代码吧。
http://www.phpwind.net/read-htm-tid-685276.html