2025上半年,最新 AI实践都在这!20+ 应用案例,任听一场议题就值回票价 了解详情
写点什么

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

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

关注

评论

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

Redis Set 用了 2 种数据结构来存储,到现在才知道

Java你猿哥

Java redis string HashMap底层原理

Spring Boot如何获取Excel sheet页?

bug菌

Spring Boot spring-boot 三周年连更

躬身入局的数科公司,为本就拥挤的数智化赛道带来了什么?

用友BIP

用友iuap 用友技术大会 数科公司

AI不会取代打工人,使用AI的人才会! | 社区征文

王中阳Go

程序员 AI GPT ChatGPT 三周年征文

大数据时代数据化转型的多种模式

星环科技

保姆教程 | 用GPU云主机搭建AI大语言模型并用Flask封装成API,实现用户与模型对话 | 京东云技术团队

京东科技开发者

flask gpu GPU服务器 企业号 4 月 PK 榜 AI大语言模型

华为ISDP数字化现场作业,如何助力电力行业安监风险管控?

YG科技

15个值得收藏的数据可视化开源工具

2D3D前端可视化开发

数据可视化 数据可视化工具 前端数据可视化 数据可视化设计 数据可视化软件

关于聚合根,领域事件的那点事---深入浅出理解DDD | 京东云技术团队

京东科技开发者

DDD 企业号 4 月 PK 榜 聚合根 领域事件

【Linux】中安装pip(详细教程)

A-刘晨阳

Python Linux 运维 pip 三周年连更

企业级统一数据平台建设思路

星环科技

数据平台

华为ISDP数字化现场作业:数字化转型助力电力行业安监风险管控

轶天下事

电力行业信息化年会 华为解读“低碳、安全、发展”新思路

YG科技

Databend Parser 快速入门

Databend

构建系列之webpack窥探上

江湖修行

前端 Web webpack cli 构建

好用的Angular组件库有哪些推荐的?TinyNG好用吗?

英勇无比的消炎药

开源 前端 angular OpenTiny

Python面试题

袁袁袁袁满

三周年连更

面面俱到!百度出品2023版Java面试指南,囊括面试所有硬核技能

程序员小毕

程序员 后端 架构师 java面试 八股文

华为ISDP工单宝应邀参加第十七届工程建设行业信息化发展大会

轶天下事

Matlab实现蚂蚁群算法

Shine

三周年征文

6个优化策略,助你降低K8S成本

SEAL安全

k8s 成本管理

企业号 5 月 PK 榜,火热开启!

InfoQ写作社区官方

热门活动 企业号 5 月 PK 榜

微信小程序开发限制

肥晨

三周年连更

低代码+智能化,企业数字化提速的又一场革命

科技热闻

第十七届工程建设行业信息化发展大会成功举办,华为工单宝表现亮眼

YG科技

华为ISDP数字化现场作业在第十七届工程建设行业信息化发展大会亮相,备受企业瞩目

轶天下事

【专栏 03】数据仓库、数据集市、数据湖,你的企业更适合哪种数据管理架构?

星环科技

数据架构

Qz学算法-数据结构篇(哈希表)

浅辄

数据结构 三周年连更

什么是软件开发领域的 obsolete 或者 deprecated 含义

汪子熙

软件开发 三周年连更

SQL数据库管理:RazorSQL 激活版

真大的脸盆

Mac 数据库管理工具 Mac 软件 数据库软件

企业如何两步实现数据资产化?

星环科技

数据资产化

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