最近在StackExchange的编程板块上引发了一场关于“Mono是否能够做为跨平台.NET”的讨论。讨论发起者提出了几点“否认”见解,包括Mono建立者Miguel de Icaza在内的许多人给出了回复。html
Thorbjorn在提问中认为Mono并不能称做是跨平台的.NET,理由以下:程序员
用户sparkie首先回应了以上几点疑问:编程
首先,CLI(Common Language Infrastructure)和.NET是有区别的,前者是公开标准,然后者是微软对这一标准的实现,Mono则是CLI的又一实现,它历来不是“可移植的.NET”。一样,C#也是一个公开标准,也不和.NET绑定在一块儿。json
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了。app
所以,若是要考虑“.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支持:除WP七、CF、XBox、MonoTouch和PS3外的全部平台 。
- CPU SIMD支持:Linux,、BSD、Solaris及MacOS X。即将支持PS 三、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:除WP七、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移植,不过他们的移植团队没有获得反馈其成果的许可。