20 年前的 2002 年 2 月 13 日,仍高举着闭源大旗的微软正式发布 Visual Studio .NET,时任首席执行官比尔·盖茨将其描述为“第一个用于构建 XML Web 服务和下一代互联网应用程序的完全集成的开发环境”。
它被创造出来的目的非常明确 —— 创建一个全新的技术体系以取代如日中天的 Java。
“临危受命”取代 Java
时间回到 2000 年 2 月,Windows 2000 刚刚发布不久,微软当时的开发平台是由 Visual Studio 6.0 组成的,它是一组独立的 IDE,旗下包括 Visual C++、Visual Basic (VB)、FoxPro、Visual InterDev 和 Visual J++。其中除了 Visual C++ 以外,其他的语言在当时或多或少都存在着一些问题。
VB 曾经非常流行,但面向对象编程语言的狂热分子经常抱怨 VB 缺乏对继承的支持,对于使用 COM 和 Windows API 的高级应用来说,VB 过于复杂,而且几乎在所有方面都被 Borland 公司的 Delphi 所取代;作为微软早期的数据库语言,FoxPro 也日薄西山,其 DBF 数据库格式并不好用,加上此时的 Access 更受欢迎,后者与 SQL 和 SQL Server 更好地兼容;Visual InterDev 是微软首次使用 Active Server Pages (ASP) 进行 Web 开发,这是一种 VB 版本的 PHP,但却没有 PHP 的易用性和跨平台功能。
值得一提的是,Visual J++ 由 Delphi 的架构师 Anders Hejlsberg 设计(他于 1996 年跳槽到微软),可以看做是微软的 Java 版本,对当时的 Windows 开发相当有利。但它的问题并不是语言本身不够好,而是其不符合 Java 规范,正面临着来自 Sun 公司的诉讼危机。
也就是说,当时的微软开发生态领着一众“老弱病残”,看起来唯一能打的在法律上也被竞争对手拿捏,面对来势汹汹的 Java,微软不得不另辟蹊径。
2000 年 7 月,时任微软平台战略集团副总裁 Paul Maritz 在微软专业开发者大会上首次公布了 .NET Framework 战略。Maritz 将该战略的重要性比作八年前随 Windows NT 引入的 Win32 API。该项目最初在开发过程中被称为 NGWS(下一代 Windows 服务),Maritz 说“我们最终选择了 .NET 这个名称,因为它代表了旨在将互联网变成真正的分布式计算平台的一组技术。”
根据 Maritz 的描述,微软最初的想法是建立一个由使用 SOAP(简单对象访问协议)的 XML 网络服务驱动的程序化网络,SOAP 是一种在互联网上交换数据的 XML 标准。Maritz 说:“我们称之为网络服务架构......我们的 .NET 平台旨在使建立这些类型的应用程序变得更加容易”。
该战略旨在通过其 Passport 目录和一组代号为 Hailstorm 的第一方 XML 服务将微软置于互联网的核心,成为互联网软件分发的中转站。该服务于次年推出,但由于涉及不正当竞争很快被放弃。
而其中的 .NET Framework 项目则保留了下来。
“这是我们长期以来的目标,将 Visual Basic、Visual C++ 和我们的其他语言置于共同的基础上……我们今天拥有第一个真正的现代通用多语言面向对象的运行时环境”,Maritz 说。
尽管该计划的“面向对象”、“跨平台”等特性与 Java 有很多共同点,Maritz 的措辞仍试图将 .NET Framework 与 Java 区分开来。在微软的宣传中,Java 只是一种编程语言,而 .NET Framework 则是一种具有可以运行各种语言的“公共语言运行时”(CLR)—— 这在今天看来似乎有点奇怪,毕竟 JVM 语言的概念在当时就已经很普遍,而如今人们印象中大多数 .NET 开发都是用 C# 来完成的 —— 但在当时,这个宣传口径对 .NET 的推广还是起了很重要的作用。
除了宣传策略外,微软甚至在 2000 年就尝试打了“开放牌”。“我们的目的是在这个公共语言运行时和这些类库中获取全部知识产权,并将它们提供给标准机构,这样它们就可以成为一套真正开放的标准,”Maritz 说。
实际上,此时的微软对开放 .NET 并不全心全意。直到 2014 年新 CEO 上任,微软才将 .NET 分叉出开源的 .NET Core,真正支持开源 .NET,并使其成为跨平台的开发环境。甚至在去年,微软还一度做出(后来又撤销了)一些会破坏开源版本的决定。当然这些都是后话了。
Java 和 .NET 的爱恨情仇
Java 对 .NET 的影响是复杂且深远的。
Sun 公司最初推出 Java 时,是有意识地试图破坏微软当时在商业计算领域的垄断地位,而 Visual J++ 和后来的 .NET 都是微软对 Java 的反击。
根据 ASP.NET 创始人之一 Mark Anders 的说法,早期 .NET 的很多技术主要来自 Visual Basic 团队。VB 团队当时正在开发一个新的运行时,该 CLR 项目代号为“Project Cool”,它不像 COM 那样复杂,而且拥有很好的对象系统和垃圾回收器,这些特性都与 JVM 很相似。
Anders 还透露,ASP.NET 的早期原型就是用 Java 编写的,“我喜欢 Java 这种语言,Scott (ASP.NET 之父、现任微软副总裁)也是。”因此,Anders 和 Scott 也成为了微软内部首批采用 VB 团队 CLR 技术的开发人员,并推动了 .NET 项目的创建。
前文提到的 Anders Hejlsberg 也是 .NET 的主要创建者。从 Borland 跳槽加入微软时,他就帮助微软构建了 Visual J++ 6.0 和 Windows Foundation Classes (WFC),尽管前者由于法律问题惨淡收场,但他很快又帮助微软创建了另一个有能力与 Java 抗衡的编程语言 C#。
刚刚面世的 C# 看起来就与 Java 有着惊人的相似。它包括了诸如单一继承、接口、与 Java 几乎同样的语法和编译成中间代码再运行的过程。但是 Hejlsberg 又在 C# 中巧妙融入了一些 Delphi 和 VB 的特性来作为与 Java 的区分,包括与 COM(组件对象模型)直接集成、将 WFC 改编为 Windows 窗体类库等,规避了很多版权纠纷,这使得 C# 顺利成为了微软 .NET 框架的主角。
日后的很多公开场合,Hejlsberg 都承认过“Java 是 .NET 的灵感来源”,但其分量与 Delphi 和 VB 相当。
见证微软转向开源
.NET 能够获得今天的地位,很大程度上归功于微软对于开源的态度转变。
在 .NET 刚刚面世的前几年,微软的决策层仍聚焦于巩固自己的专利护城河,这使得 .NET 在很长一段时间里只能用于 Windows 平台,缺乏其发布会时所提出的跨平台能力,这对 .NET 在非 Windows 用户群体中的推广造成了阻碍。
2004 年,一个来自微软外部的开源项目 Mono 横空出世,率先为 .NET 的跨平台工作提供了非官方的支持。
Miguel de Icaza 是 Xamarin 公司的创始人之一,同时也是 Mono 项目的发起者。在接触 .NET 之前,de Icaza 的另一个身份是知名 Linux 桌面环境 GNOME 的创始人。Icaza 接受媒体采访时提到,自己对于 .NET 的兴趣源于为 GNOME 应用程序寻找更好的编程工具。
“当我们刚开始创建 GNOME 时,那个时代的 Unix 世界有一个基于高级语言降低编程复杂性的方案,一个叫 John Ousterhout 的人构建了一种名为 TCL 的语言和一个称为 TK 的 UI 工具包,用这套工具来构建应用程序很有趣,但问题是 TCL 并不是一种出色的编程语言。”Icaza 说。
Icaza 和 GNOME 团队其他成员还尝试使用过 Java,但 Java 的即时编译器 JIT 在当时发展有限,工具包也还不够完善。于是 GNOME 团队最终使用了一个由 C 语言编写的 GUI 应用程序开源工具包 GTK。“GTK 符合我们的要求,但它是用 C 编程的,我们真的想让它可以支持多种更高级的编程语言。”de Icaza 说。
采用 GTK 后,GNOME 团队为包括 Objective-C、ADA、Perl、Python、C++ 和 Scheme 在内的语言创建了绑定协议。“我们的想法是将编程保持在一个高度抽象的水平上,但是存在着一些性能问题。当 .NET 出现的时候,它满足了很多要求。它是一种高水平的语言,有较快的编译速度,且没有受到当时脚本语言的一些弊端的影响。”
de Icaza 说,Mono 最初只是基于 .NET 的“ECMA 子集”,并补充了自己的技术栈,但是随着社区的壮大,越来越多的人向 Mono 贡献代码,使得其陆续获得 ADO.NET,ASP.NET 和 Windows Forms 的能力,逐渐成长为官方 .NET Framework 的开源、跨平台替代品。
对于 Mono 社区的活跃,微软内部在当时分为了两派,一部分人选择支持,一部分人则保持警惕。支持者的观点很简单,Mono 确实为 .NET 带来了他们当初承诺的跨平台特性,这对 .NET 的推广是百利而无一害的;而反对派大多数则是闭源时代的残党,毕竟想要这艘在专有软件大海上驰骋超过 30 年的巨轮突然转向绝非易事,更何况此时的掌舵人仍是当年那个喊出“Linux 就是毒瘤”的鲍尔默。
这样的情况导致微软在那段时间里对待 Mono 社区的态度非常微妙 —— 出于商业策略考虑,微软通常会在公开场合介绍 .Net 平台的时候顺带提及一下 Mono,以证明自己的跨平台性;但始终没有从官方角度对 Mono 社区提供任何实质性的支持。
直到 2014 年,微软新 CEO 纳德拉上任。在发布会上,他在人前表现得颇为和善,谈话也比较婉转,散发着与鲍尔默完全不同的领袖气质,但是他话语中透出的意思却非常地明确:Windows 未来将不再具备从前的重要地位,云和移动才是微软未来的核心。
从这时起,微软打出了“拥抱开源”的旗号。而他们做的第一件事,就是官方支持 .NET 的跨平台工作。
与此同时,Xamarin 公司使用 Mono 编写的游戏开发引擎 Unity 在移动领域取得巨大成功。移动设备上对 .NET 的需求使得微软的业务部门加强了与 Mono 团队的合作。最终在 2016 年,微软正式收购 Xamarin,完成对 Mono 的收编,以实现 .NET 在移动端的布局。
收购 Mono 以后,微软也推出了首个官方开源的 .NET 版本 .NET Core。.NET Core 实现了 .NET Framework 不含用户界面的部分功能,例如 JIT (.NET Core 采用 RyuJIT)、垃圾收集器 (GC) 以及类型 (包含基本类型以及泛型类型等)。
根据微软官方的描述,.NET Core 与 Mono 未来会是合作的关系,Mono 仍会维持社区力量的维护与发展,而 .NET Core 则会以官方角度来进行发展,两边也会一起进行彼此功能上的增进。
可以说,.NET 与开源社区的拉扯正是微软过去十年从闭源向开源转变的缩影。
.NET 的未来
根据 StackOverflow 的调查,.NET 在“最受喜爱”技术类别中名列前茅,并且已连续三年位居榜首。.NET 项目管理负责人 Scott Hunter 表示,“.NET 活跃用户的数量正在增长。我们每年新增用户超过 540 万。”
Hunter 引用了云原生计算基金会 CNCF 的数据,在去年 .NET 6.0 刚发布时,该项目在上升速度最快的开源项目中排名第一,此后下降到了 3-4 名,但自 2017 年以来,.NET 一直排在前 30 名以内。
同样值得注意的是,.NET 应用程序在 Linux 上的部署也越来越多。“今年某个时候,将有超过一半的 .NET 6.0 及以下版本的 WEB 应用部署在 Linux 上。”Hunter 说。
尽管增长数据喜人,但 .NET 在开源社区中一直以来仍存在很多争议。
例如它仍然主要依赖于微软一家公司,这让社区一部分人一直对其中立性保持担忧。去年 10 月, .NET 社区删除热重载功能,强制用户改用昂贵但功能强大的 Visual Studio 2022 就引发了巨大的争议。虽然微软方面很快撤销了这一举措并公开道歉,但这一事件也让其花费多年在开源社区中建立起来的信任出现了裂痕。
.NET 基金会公布的一份调查也显示,目前 .NET 相关的开源社区成员主要由倾向于 Windows、微软的平台和更有经验的开发人员组成,这表明 .NET 对新程序员的吸引力仍然十分有限。
回顾 .NET 的历史,作为一个综合开发环境,其在多语言方面只取得了部分成功,大多数 .NET 开发者使用的语言只有 C#,使用 VB 的开发者数量正在不断下降,而 F# 用户基数则小到可以忽略不计。
但毫无疑问的是,微软在 2014 年官方支持跨平台以及后续不断拥抱开源的举措,确实帮助 .NET 取得了巨大的成功。虽然并没有像 Maritz 20 多年前所希望的那样完全取代 Java,但 C# 和 .NET 平台取得的成绩已经足够瞩目。