写点什么

讨论:“Mono 是个跨平台的.NET”是否是个正确的说法

  • 2010-11-30
  • 本文字数:4194 字

    阅读完需:约 14 分钟

最近在 StackExchange 的编程板块上引起了一场关于“Mono 是否可以作为跨平台.NET”的讨论。讨论发起者提出了几点“否定”看法,包括Mono 创建者 Miguel de Icaza 在内的许多人给出了回复。

Thorbjorn 在提问中认为 Mono 并不能称作是跨平台的.NET,理由如下:

  • OpenJDK 等 Java 提供商都通过了官方的 Sun TCK 来保证正常工作,Mono 似乎并没有通过 Microsoft TCK。
  • Mono 的发布总是落后于.NET,那么目前它又对.NET 支持到什么程度呢?
  • 如 WinForm 等 GUI 工具是否可以在 Mono 下正常工作?
  • 商业用户不会将开源框架作为备选方案。

用户 sparkie 首先回应了以上几点疑问:

首先,CLI(Common Language Infrastructure)和.NET 是有区别的,前者是公开标准,而后者是微软对这一标准的实现,Mono 则是 CLI 的又一实现,它从来不是“可移植的.NET”。同样,C#也是一个公开标准,也不和.NET 绑定在一起。

Mono 相对于.NET 是有些落后,但也只有一丁点而已。Mono 可以运行 C# 4.0 的代码(最新的.NET 版本),与此同时微软最近把所有的 DLR 代码都开源了(使用 Apache 2.0 授权协议),这意味着 mono 可以直接使用 IronPython,IronRuby,同时 F#也不久前也已经开源,再加上微软都会定期发布.NET 的 CTP 版本,因此 Mono 开发人员几乎可以时刻和.NET 保持同步。.NET 中的部分工具和扩展,如 Code Contract 等等,它们并没有 mono 中的完整实现,不过它们的使用并不广泛。如果这些扩展变得流行起来了,那么 Mono 也会提供对应的实现。

WinForm 没有得到完整的移植,因为它们是.NET 的特性功能,而并非 CLI 的一部分。CLI 中并没有定义特定的组件库。有一些组件库是跨平台的,例如 GTK#和 Silveright,如果你从编写应用程序的一开始就考虑到可移植性,那就不应该使用 WinForm/WPF。此外,Mono 提供了一个很薄的封装层,现有的 WinForm 应用程序可以可以比较容易地移植为 GTK#(不需要完全重写)。

Mono 提供了一个工具:Mono Migration Analyser(MoMA),它能检查一个.NET 应用程序能否移植到 Mono 上(如,是否使用了不可移植的类库,或是 P/Invoke)。

对于不愿意使用开源产品的商业应用,Mono 可以使用另一种授权方案,这时候 Mono 代码的归属权则交由 Novell 负责,此时授权方案便不是 LGPL 了。

因此,如果要考虑“.NET 可否移植”这个命题,我想如果你从一开始就考虑到框架的可移植性问题,则它是成立的。但如果换个说法“我有个使用.NET 开发的 Windows 应用程序,它应该可以在 Mono 上运行”,那就不正确了——不过 Mono 让移植这样的应用程序变得简单许多。

随后 Lloeki 谈论了他的工作方式:

除了技术方面的因素以外,关键还是在于编写代码的方式。

无论是哪种跨平台的应用程序(例如 Java,Python,Ruby……),如果在写代码时不考虑可移植性,那么你应该假设这些代码可以直接跨平台执行的可能性为零(即使实际上这样的可能性要高出许多)。你无法随便拿到一个程序集就保证它能在 Mono 下正确执行。

不过对于一个新项目(或是你可以轻易重构的项目),选择.NET/Mono 作为可移植的方案之一则是明智的,不过对于跨平台的代码来说,你还是需要不断地进行测试。如果你使用持续集成,那么只要简单的创建一个 Mono 构建的节点即可。只要养成良好的习惯(例如路径的分隔符),很多问题可以在开发阶段就解决掉,而绝大部分代码只要使用单元测试以及其他一些常见的实践方式,再加上一点点先期规划就能得到很好的跨平台性。剩下的,例如平台相关的代码(如 P/Invoke),则可以通过封装,为不同平台提供针对性的实现。这样产出的项目,几乎不会付出额外的代价就能得到很好的移植性。

当然,使用一个 Mono 中不存在或是不兼容的类库则另当别论,不过就我的个人而言还没有遇到这样的情况。这些是我们在工作中实际用到的做法,我可以放心的声称“.NET+Mono”是跨平台的解决方案。

对于 Mono 于.NET 功能的支持程度, Robert Michael 谈到:

我用过 Mono,我认为它就和其他开源平台一样好,只不过不是微软直接支持的而已。如果你能接受 Clojure 或 Scala 这样的开源项目,那么 Mono 也能让你满意。Mono 对于.NET 的支持程度可以参考 Mono Roadmap 页面。Mono 并不等同于.NET,它们有或多或少的区别,例如现在你还无法使用 Entity Framework。

Mono 不是.NET 的移植品,有些技术是 Mono 不会或不打算实现的(如 Workflow Foundation 或 WPF),此外它们还提供了微软.NET 外的其他一些技术,例如 SIMD 扩展。简单地说,Mono 和微软.NET 是基于相同基础——CIL 和 BCL——的两个不同项目。

在讨论中,Mono 创建者 Miguel de Icaza 给出了最为详细的回应:

“.NET 是否跨平台”是一个模糊的说法,无论是框架本身还是整体环境都在不断改变。

简单地说,作为.NET 的基础架构,CLI 标准是跨平台的,但如果要在不同平台上得到最好的体验,则势必要使用各自平台上有针对性的 API。CLI 技术家族从来没有试着要“一次编写,到处执行”,好比电话和大型机的区别实在是太大了。与其为不同平台提供统一的 API 和运行时,不如各自平台上的最佳体验提供最正确的工具。试想那些非 Windows PC 或 Unix 服务器的程序员,要知道如今已经出现了游戏设备,移动电话,机顶盒,分布式集群等太多激动人心的平台。

微软的.NET 框架不是跨平台的产品,它只能运行在 Windows 上。其他系统上还有一些.NET 框架的变体,例如 Windows Phone 7,XBox 360 和浏览器中的 Silverlight,它们都有些许不同的配置(Profile)。

如今你已经可以在各个主流的操作系统,电话,移动设备,嵌入式系统或是服务器上使用基于.NET 的技术,以下是各种 CLI 实现的列表,虽不完整,但应该可以覆盖 99% 的情况:

  • 基于 x86 和 x86-64 的计算机:
    • Windows:一般来说你会使用.NET 或 Silverlight,不过你也可以使用完整的 Mono。
    • Linux, BSD 或 Solaris:完整的 Mono 或 Silverlight。
    • MacOS X:完整的 Mono 或 Silverlight。
    • Android:Mono 及 Android 的子集。
  • ARM 计算机:
    • Windows Phone 7:Compact Framework 2010。
    • Windows 6.5 及更早:早期的 Compact Framework。
    • Android 设备:Mono/Android。
  • PowerPC 计算机:
    • 在 Linux,BSD 或 Unix 操作系统上使用完整的 Mono 功能。
    • 在嵌入式系统中使用 Mono,如 PS3,Wii。
    • 在 XBox36 上运行 Compact Framework。
  • S390, S390x, Itanium, SPARC 计算机:
    • 完整的 Mono 支持
  • 其他嵌入式操作系统:
    • .NET MicroFramework 或 Mono 的移动配置。

有时候相同的代码很难四处运行。例如 XNA 代码不会在每个桌面上运行,反之亦然。为了.NET 不同的配置里运行,你需要修改些许代码。以下是我所了解的一些配置:

  • .NET 4.0 配置
  • Silverlight 配置
  • Windows Phone 7 配置
  • XBox360 配置
  • Mono 核心配置:与.NET 配置相同,可以在 Linux,MacOS X,Solaris,Windows 和 BSD 里使用。
  • .NET Micro Framework
  • Mono 的 iPhone 配置
  • Mono 的 Android 配置
  • Mono 的 PS3 配置
  • Mono 的 Wii 配置
  • Moonlight 配置(与 Silverlight 兼容)
  • Moonlight 扩展配置(Silverlight 和完整的.NET 4 API)

以上配置都有多多少少的不同,这不是坏事。每个配置的设计都适应其平台,去除任何一个都是不明智的。例如,Silverlight API 可以控制浏览器,这不关电话什么事;由于缺少合适的支持,XNA 的着色功能对 PC 硬件也没有多少意义。你越早认识到.NET 不是个将开发人员绑定在特定硬件或平台上的解决方案,就能越早成为更好的开发人员。

这意味着,有些 API 或解决方案可以在多个平台中使用,例如 ASP.NET 可以用在 Windows,Linux,Solaris,MacOS X 上,因为.NET 和 Mono 都提供了这些 API。同时,ASP.NET 则无法在某些微软支持的平台上使用,例如 XBox 或 Windows 7,也不支持 Mono 的 Wii 和 iPhone 配置。

其他解决方案的本质也是一样的。要完整列出这些技术需要一张复杂的表格,我不知道如何在这里表现出来,不过这里有个特定技术与特定平台的列表:

核心运行时引擎(所有平台):

  • Reflection.Emit 支持:除 WP7、CF、XBox、MonoTouch 和 PS3 外的所有平台 。
  • CPU SIMD 支持:Linux,、BSD、Solaris 及 MacOS X。即将支持 PS 3、MonoTouch 和 MonoDroid。
  • Continuations - Mono.Tasklets:Linux、BSD、Solaris、MacOS、PS3 及 Wii。
  • 程序集卸载:只有 Windows。
  • VM 注入:Linux、BSD、MacOS X 及 Solaris。
  • DLR:Windows、Linux、MacOS X、Solaris 及 MonoDroid。
  • 泛型:在 iPhone 和 PS3 上存在一些限制。

语言:

  • C# 4:所有平台。
  • C# 编译器即服务:Linux、MacOS、Solaris、BSD 及 Android。
  • F#、IronRuby 及 IronPython:除 WP7、CF、Xbox、MonoTouch 及 PS3 外的所有平台。

服务器技术:

  • ASP.NET:Windows、Linux、MacOS、BSD 及 Solaris。
  • ADO.NET:所有平台
  • LINQ to SQL:所有平台
  • Entity Framework:仅 Windows
  • XML 核心技术:所有平台
    • XML 序列化:除 WP7,CF 和 XBox 外的所有平台。
  • LINQ to XML:所有平台
  • System.Json:Silverlight,Linux,MacOS,MonoTouch,MonoDroid(译注:可移植到其他平台
  • System.Messaging:Windows、Linux、MacOS 和 Solaris 的支持则需要 RabbitMQ。
  • .NET 1 Enterprise Services:仅 Windows。
  • WCF:完整版仅支持 Windows。Silverlight、Solaris、MacOS、Linux、MonoTouch、MonoDroid 支持其自己。
  • Windows Workflow:仅 Windows。
  • Cardspace identity:仅 Windows。

GUI 技术:

  • Silverlight:Windows、Mac 和 Linux(Moonlight)
  • WPF:仅 Windows
  • Gtk#:Windows、Mac、Linux 及 BSD
  • Windows.Forms:Windows、Mac、Linux 和 BSD
  • MonoMac - 原生 Mac 集成:仅 Mac
  • MonoTouch - 原生 iPhone 集成:仅 iPhone/iPad
  • MonoDroid - 原生 Android 集成:仅 Android
  • Media Center API:仅 Windows
  • Clutter:Windows 和 Linux

图像类库:

  • GDI+:Windows、Linux、BSD 及 MacOS
  • Quartz:MacOS X、iPhone 及 iPad
  • Cairo:Windows、Linux、BSD、MacOS、iPhone、iPad、MacOS X、PS3 及 Wii

Mono 类库 - 跨平台,可以在.NET 里使用,不过需要手动编译:

  • C# 4 编辑器及服务
  • Cecil - CIL 操作,工作流,CIL 探测,链接器
  • RelaxNG 类库
  • Mono.Data.* 数据提供者
  • 完整的 System.Xaml(用于安装程序,.NET 没有提供这个技术)

MonoTouch 为 iPhone 上运行的 Mono,MonoDroid 为 Andriod 上运行的 Mono。PS3 和 Wii 的移植只供索尼和任天堂认证的开发人员使用。

在讨论中 Miguel de Icaza 还表示,IBM 至少完成了两个针对 AIX 的 Mono 移植,不过他们的移植团队没有得到反馈其成果的许可。

2010-11-30 04:147482
用户头像

发布了 157 篇内容, 共 61.5 次阅读, 收获喜欢 6 次。

关注

评论

发布
暂无评论
发现更多内容

选择小程序第三方开发框架,你需要知道这些

没有用户名丶

TDengine 成功“晋级” Percona Live 2023 银牌赞助商,开发者驻足关注

爱倒腾的程序员

OpenHarmony创新赛 | 赛事宣讲会日期重磅官宣!为你带来超详尽的赛事攻略

OpenHarmony开发者

OpenHarmony

ps神经滤镜是干什么的,神经滤镜的功能和作用

Rose

Photoshop 2023下载 ps神经滤镜 Neural Filters滤镜

优质高效!阿里甩出SpringBoot巅峰之作,进阶不二之选

Java Spring Boot 框架

完美!京东资深架构师爆肝纯手打700页架构进阶宝典我粉了

Java 架构 亿级流量

iMovie for Mac(专业视频剪辑工具) v10.3.6中文版

Rose

Mac视频剪辑软件 iMovie中文版 iMovie下载 iMovie Mac破解版

名不虚传!字节技术官甩出的"保姆级"数据结构与算法笔记太香了

Java 数据结构 算法 LeetCode

顺丰科技携手飞桨自研“智能外呼机器人”,为客户打造优质服务体验

飞桨PaddlePaddle

nlp 语音识别 百度飞桨

Nautilus Chain开启全球行,普及Layer3概念加速其采用

鳄鱼视界

浅析 Redis 中 String 数据类型及其底层编码

redis 数据结构 string

前端微服务无界实践 | 京东云技术团队

京东科技开发者

微服务 前端 企业号 5 月 PK 榜 无界

从传统 IT 容灾转向“全栈云容灾”|什么是更适合政企的云

云布道师

阿里云

Github标星67.9k的微服务架构以及架构设计模式笔记我粉了

Java 架构 微服务 设计模式

PAI-Diffusion中文模型全面升级,海量高清艺术大图一键生成

阿里云大数据AI技术

人工智能 模型 Stable Diffusion 企业号 5 月 PK 榜

MacOS高效iOS代码编写工具|AppCode 2023 激活版v2023.2 兼容M1/M2/intel

Rose

AppCode中文 AppCode 2023破解 AppCode密钥 iOS/macOS开发

运行Adobe软件遇到“Adobe app is not available”怎么解决

Rose

Adobe软件

如何做好需求管理?华为云需求管理利器CodeArts Req解读

云计算 产品经理 需求管理 华为云

Iframe在Vue中的状态保持技术 | 京东云技术团队

京东科技开发者

html Vue iframe 跨域 iframe 企业号 5 月 PK 榜

Photoshop2023硬件要求,PS2023最低配置要求

Rose

PS2023 PS2023系统要求 Photoshop2023硬件要求 神经滤镜Neural Filters

首站中科院!百度商业AI技术创新大赛开启巡回宣讲

百度Geek说

人工智能 百度 企业号 5 月 PK 榜

Spring Validated 校验框架,让你的项目更简洁,提升开发效率

Java spring Validated

开源堡垒机和免费商业堡垒机哪个用的更香?

行云管家

开源 网络安全 免费堡垒机

火山引擎DataTester:如何使用A/B测试优化全域营销效果

字节跳动数据平台

AB testing实战 ab测试 A/B测试

字节Java全能手册火了!多线程/网络/性能调优/框架啥都有

Java 微服务 Spring Cloud socket

如何编写一个健壮的 npm 包 | 京东云技术团队

京东科技开发者

npm npm chalk-next 企业号 5 月 PK 榜

百度营销首创CPQL模式,破解汽车营销线索难题

极客天地

万字长文详述ClickHouse在京喜达实时数据的探索与实践 | 京东云技术团队

京东科技开发者

数据库 flink Clickhouse 企业号 5 月 PK 榜

阿里逆天级调优方案,内部这套Java性能调优实战宝典,堪称教科书

Java 性能优化 JVM 性能调优

CFS第十二届财经峰会7月举行, 候选品牌:行云管家

行云管家

云计算 商业 财经峰会

首个机器学习实时特征平台测试基准论文被 VLDB 2023 录取

第四范式开发者社区

人工智能 机器学习 数据库 开源 特征

讨论:“Mono是个跨平台的.NET”是否是个正确的说法_.NET_赵劼_InfoQ精选文章