简单讲讲:
我估计大多数程序员对于C# 5.0之后的改进都没有什么太多的认知,的确从C# 5.0开始C#已经没什么太多东西可以从其他语言借鉴,Anders的重心也开始逐步倾斜到TypeScript,所以从5.0引入async之后C#语言发展速度开始减缓了。
C#6引入了大量的语法糖,例如?.和$""等等都是6.0引入的,这些东西极大的简化了C#的语法,而C#7.0则进一步的引入了元组、残破的模式匹配支持和本地函数以及意义深远的ref和readonly支持的扩大化,ref和readonly ref使得Span<T>系列类型得以引入从而改善了特定场景的性能。更重要的是这些语言层面上的改进使得类库作者可以写出特定场景的高性能代码而避免引入C/C++。至于out变量声明和throw表达式则是早就该加入的东西并没有什么太多的悬念。
值得注意的是7.0开始搞出了小版本号的概念,C#7事实上有四个版本,C#7.0、7.1、7.2和7.3,
C#8.0将在2019年发布,主要的改进包括一个破坏性修改,可空引用类型,估计届时要启用这个特性需要加编译参数,或者可以用编译参数屏蔽这个特性。这个特性据说是从Kotlin借鉴过来的,这怕是C#出现18年来第二次从Java阵营借鉴(第一次是诞生)。
其他的改进则有相对完整的模式匹配支持(虽然还很丑,而且没有UnionType/SumType还是残废),以及接口默认实现方法(这个倒是Java发明的,用来取代C#当年的扩展方法的用途,然后被C#再抄回去)。语法层面上async stream和Range可以大大简化特定场景的语法。
很明显微软现在将重心放在了.NET Core这一边,当然.NET Framework历史包袱太多,如果我是微软的程序员也愿意把精力放在.NET Core的框架开发上。结果就是.NET Framework 4.8一直难产,而.NET Core则一路高歌从1.0演化到3.0。
为了平滑的迁移现有应用程序,微软在.NET Core上重新实现了大部分的.NET Framework的API,当然GUI的除外,尽管如此微软还是提供了GDI的部分API的实现也就是System.Drawing。
而http://ASP.NET部分则因为历史包袱太多被全部重写,事实上我非常赞成这一决定。尽管http://ASP.NET Core是全部重写的,但是Razor和MVC的大部分语法和功能被保留下来,所以原有MVC的应用也能轻松迁移。不过,Razor的helper功能被移除仍然让我非常不爽。
新的TagHelper我认为是非常正确的道路,而事实上这就是十年前我的Jumony for MVC尝试做的事情。
最后聊聊平台和生态。
事实上C#和Java就是一种语言……基本上你可以认为这两者的亲缘关系就像是JavaScript和TypeScript。所以说如果你会C#那是没有道理看不懂或者写不了Java代码的。当然反过来会有点麻烦(如果你会Kotlin的话,可能更有助于学会C#)。这就像你会TS肯定能看懂JS一样……
所以纠结语言是没有什么意义的,C#和Java的主要差别在于库函数,这也是目前阻碍两边程序员跨界的重要因素。Java哔一样的语法很多时候并不是我最难以忍受的,更难以忍受的是哔一样的基础类库。
在BCL这一块,微软是毋庸置疑的Top 1。当然,在互联网时代,微软的老派作风使得对新技术和新思想的响应速度不如开源社区,尤其是对Linux和开源社区并不明朗的态度,这使得.NET诞生的这十几年来一直未能取代Java,甚至让后者做大做强。
开源的精神内核是开放,作为一个老派的程序员(掐指一算入行都二十年了),我觉得开放的心态是我还能活跃在一线写代码的原因。Java开源社区有很多好东西,也经过了很多项目的检验,.NET其实也是可以用的,毕竟,其实C#本来就是从Java改进而来,他们之间的共同点比差异多太多了。互操作性也远比其他语言容易得多,他们都是把元数据嵌到程序集里面的。
我现在做.NET Core的应用,用Eureka和Consul做服务发现,用apollo做配置中心,所有这些都不是C#写的而是Java写的,但这丝毫没有任何问题。开源的生态本来就是开放的,在我看来,未来是各种语言混合互操作的天下,虽然和.NET最开始的愿景在细节上有些偏差。但是我认为未来本来就不会用生态和语言来划分程序员……