討論:“Mono是個跨平臺的.NET”是否是個正確的說法

來源: InfoQ  發布時間: 2010-12-06 10:08  閱讀: 1259 次  推薦: 0   原文鏈接   [收藏]  
摘要:最近在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移植,不過他們的移植團隊沒有得到反饋其成果的許可。

0
0
 
 
 

文章列表

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()