AI实践哪家强?来 AICon, 解锁技术前沿,探寻产业新机! 了解详情
写点什么

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

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

关注

评论

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

MySQL的varchar字段最大长度真的是65535吗?

Java你猿哥

MySQL 后端 SSM框架 varchar

右键助手:MouseBoost PRO mac激活版

真大的脸盆

Mac Mac 软件 鼠标增强工具 鼠标辅助软件

大厂面试难?对标大厂“Java系统性能优化实战”二面阿里轻松搞定

Java你猿哥

面试 性能优化 SSM框架 Java性能优化

搭建一站式OpenHarmony设备开发Windows开发环境。

坚果

OpenHarmony 三周年连更

第二届中国国际软件发展大会|华为:构筑坚实软件根基,赋能数字经济高质量发展

极客天地

Spring Boot过滤器实现项目内接口过滤

Java你猿哥

Java Spring Boot SSM框架

某程序员:被裁了要求公司足额补缴全部公积金,一次补二十多万!

Java你猿哥

Java 程序员 SSM框架

和 if else说再见,SpringBoot 这样做参数校验才足够优雅!

Java你猿哥

Java spring Spring Boot ssm if-else

企业微信接入系列-上传附件资源

六月的雨在InfoQ

企业微信 三周年连更 企业微信接入 企微上传附件

大数据Hadoop之——HDFS小文件问题与处理实战操作

Openlab_cosmoplat

hdfs 开源社区 大数据Hadoop

BSN-DDC基础网络详解(九):跨链机制

BSN研习社

破防了!阿里用17个真实企业级项目阐述Java系统分析与架构设计

Java你猿哥

微服务架构 架构设计 Java系统性能 Redis开发与运维 MySQl部署

一次「找回」TraceId的问题分析与过程思考

Java 中间件 raceId

行业分析| 新的学习方式——在线自习室

anyRTC开发者

音视频 在线教育 视频直播 直播连麦 在线自习室

从原理聊JVM(一):染色标记和垃圾回收算法

京东科技开发者

Java JVM 三色标记 垃圾回收器 企业号 4 月 PK 榜

微服务 Spring Boot 整合Redis分布式锁 实现优惠卷秒杀 一人一单

Bug终结者

redis 底层原理 三周年连更

海通证券与易观千帆达成合作,构建优质客户生态圈

易观分析

金融 证券 经济

校企共建|阿里云与重庆大学人才培养交流会顺利举行

云布道师

阿里云

【4.14-4.21】写作社区优秀技术博文一览

InfoQ写作社区官方

热门活动 优质创作周报

深度学习基础入门篇[六(1)]:模型调优:注意力机制[多头注意力、自注意力],正则化【L1、L2,Dropout,Drop Connect】等

汀丶人工智能

人工智能 机器学习 深度学习

Spring Boot如何使用Undertow容器?超级详细,建议收藏

bug菌

Spring Boot 三周年连更 Undertow

DataEase 对接明道云展示表格应用数据

搞大屏的小北

数据可视化 明道云 对接api 展示明道云

震撼!阿里架构师全新产出Java面试突击宝典。Github标星疯涨!

Java你猿哥

spring Spring Boot JVM mybatis java面试

中移链合约常用开发介绍(三)工程化开发智能合约

BSN研习社

从原理聊JVM(一):染色标记和垃圾回收算法

小小怪下士

Java 程序员 后端 JVM

解决90%的面试!GitHub新兴“java面试手册 2023” 一网打尽BAT大厂

Java你猿哥

Java MySQL Spring Boot JVM MySQL面试

数智融合,生态链接丨 亚信科技“信伙伴”交流会(成都站)成功举办

亚信AntDB数据库

AntDB AntDB数据库 企业号 4 月 PK 榜

css实现瀑布流效果

格斗家不爱在外太空沉思

CSS 三周年连更

进击的 Java !

OpenAnolis小助手

Java 开源 云原生 GOTC 龙蜥技术

薪资结构重铸: Zebec将业务范围扩大到Web2薪资管理领域

鳄鱼视界

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