写点什么

讨论:“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:147418
用户头像

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

关注

评论

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

如何利用JobLeap.cn找到第一份实习

安全乐谷

找工作 秋招 春招 找实习

安全,稳定可靠的政企即时通讯数字化平台

BeeWorks

即时通讯 IM 企业级应用

什么是新一代智能职业发展平台?jobleap.cn领导的新一代求职平台与传统App有何不同?

安全乐谷

求职 找工作 秋招 春招

谷歌云授权代理|90%用户不知道的5个谷歌云免费实用技巧

Cloud Ace 云一

谷歌云

BeeWorks:构建企业智能数字化协作中枢,实现办公与业务系统的无缝整合

BeeWorks

即时通讯 IM 企业级应用

时序数据库 IoTDB 集成 DBeaver,简易操作实现时序数据清晰管理

Apache IoTDB

React-native新架构

溪抱鱼

前端 React 框架

如何利用jobleap.cn更有效地转行以及找到满意的工作

安全乐谷

找工作 简历 秋招 春招 找实习

全球通信产业展会风向标|2025中国信息通信展9月在京召开

AIOTE智博会

通信展 信息通信展 北京通信展

ETL怎么实现多流自定义合并?

RestCloud

Java join ETL 数据集成工具 多流合并

火热邀测!DataWorks数据集成支持大模型AI处理

阿里云大数据AI技术

人工智能 数据分析 数据处理 #大数据 Dataworks

华东站最后席位丨精彩嘉宾阵容,完整日程揭秘!2025 Altair 区域技术交流会邀您共探 AI + 仿真的智能未来

Altair RapidMiner

人工智能 AI 汽车 数字孪生 CAE

ActiveMQ 可观测性最佳实践

观测云

Activemq

为什么说JobLeap.cn是文科生找工作的最佳选择?

安全乐谷

找工作 应届生 秋招 春招 找实习

智能驾驶感知算法任务简介

地平线开发者

自动驾驶; 算法工具链 地平线征程6

优哩哩是什么平台?

web3区块链创业团队DappNetWork

MySQL性能优化策略及高可用架构设计与实践+监控与运维自动化!

程序员高级码农

MySQL 编程 程序员

Alluxio AI助力知乎千卡模型训练

Alluxio

掘金社区 MCP 上线、Claude 4与Gemini 2.5正面交锋、AI编程助手能力再进化—掘金 AI 编程社区周刊

Captain

Databend 产品月报(2025年5月)

Databend

傻瓜式一键部署你的网页,让全世界看见你的想法

Captain

韩国电商巨头Coupang 如何利用分布式缓存加速机器学习模型训练

Alluxio

机器学习 AI 模型训练 电商平台 Coupang

iVX+ARM 边缘计算技术架构解析:从底层架构到行业应用

代码制造者

懒懒笔记 | 课代表带你梳理【RAG课程 9&10:大模型微调与思维链蒸馏】

商汤万象开发者

iVX:图形化编程工程化实践及技术演进

代码制造者

传统企业如何玩转平台工程?2 个运维靠它管 50 + 应用

北京好雨科技有限公司

云原生 k8s rainbond 企业号 5 月 PK 榜

大数据-01-基础环境搭建 超详细 Hadoop Java 环境变量 3节点云服务器 2C4G XML 集群配置 HDFS Yarn MapRedece

武子康

大数据 hadoop mapreduce hive

低代码是什么?2025技术详解:平台分类、用户群体与发展趋势

优秀

低代码 低代码开发 低代码平台

为什么JobLeap.cn的新一代智能职业发展平台比传统求职软件更有效

安全乐谷

求职 找工作 秋招 春招 找实习

优哩哩的推广模式是什么?

web3区块链创业团队DappNetWork

HarmonyOS实战:腾讯IM之聊天列表搭建(一)

IT小码哥

鸿蒙 HarmonyOS NEXT harmoyos 腾讯IM

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