|
Thorbjorn在提問(wèn)中認(rèn)為Mono并不能稱(chēng)作是跨平臺(tái)的.NET,理由如下:
- OpenJDK等Java提供商都通過(guò)了官方的Sun TCK來(lái)保證正常工作,Mono似乎并沒(méi)有通過(guò)Microsoft TCK。
- Mono的發(fā)布總是落后于.NET,那么目前它又對(duì).NET支持到什么程度呢?
- 如WinForm等GUI工具是否可以在Mono下正常工作?
- 商業(yè)用戶(hù)不會(huì)將開(kāi)源框架作為備選方案。
用戶(hù)sparkie首先回應(yīng)了以上幾點(diǎn)疑問(wèn):
首先,CLI(Common Language Infrastructure)和.NET是有區(qū)別的,前者是公開(kāi)標(biāo)準(zhǔn),而后者是微軟對(duì)這一標(biāo)準(zhǔn)的實(shí)現(xiàn),Mono則是CLI的又一實(shí)現(xiàn),它從來(lái)不是“可移植的.NET”。同樣,C#也是一個(gè)公開(kāi)標(biāo)準(zhǔn),也不和.NET綁定在一起。
Mono相對(duì)于.NET是有些落后,但也只有一丁點(diǎn)而已。Mono可以運(yùn)行C# 4.0的代碼(最新的.NET版本),與此同時(shí)微軟最近把所有的DLR代碼都開(kāi)源了(使用Apache 2.0授權(quán)協(xié)議),這意味著mono可以直接使用IronPython,IronRuby,同時(shí)F#也不久前也已經(jīng)開(kāi)源,再加上微軟都會(huì)定期發(fā)布.NET的CTP版本,因此Mono開(kāi)發(fā)人員幾乎可以時(shí)刻和.NET保持同步。.NET中的部分工具和擴(kuò)展,如Code Contract等等,它們并沒(méi)有mono中的完整實(shí)現(xiàn),不過(guò)它們的使用并不廣泛。如果這些擴(kuò)展變得流行起來(lái)了,那么Mono也會(huì)提供對(duì)應(yīng)的實(shí)現(xiàn)。
WinForm沒(méi)有得到完整的移植,因?yàn)樗鼈兪?NET的特性功能,而并非CLI的一部分。CLI中并沒(méi)有定義特定的組件庫(kù)。有一些組件庫(kù)是跨平臺(tái)的,例如GTK#和Silveright,如果你從編寫(xiě)應(yīng)用程序的一開(kāi)始就考慮到可移植性,那就不應(yīng)該使用WinForm/WPF。此外,Mono提供了一個(gè)很薄的封裝層,現(xiàn)有的WinForm應(yīng)用程序可以可以比較容易地移植為GTK#(不需要完全重寫(xiě))。
Mono提供了一個(gè)工具:Mono Migration Analyser(MoMA),它能檢查一個(gè).NET應(yīng)用程序能否移植到Mono上(如,是否使用了不可移植的類(lèi)庫(kù),或是P/Invoke)。
對(duì)于不愿意使用開(kāi)源產(chǎn)品的商業(yè)應(yīng)用,Mono可以使用另一種授權(quán)方案,這時(shí)候Mono代碼的歸屬權(quán)則交由Novell負(fù)責(zé),此時(shí)授權(quán)方案便不是LGPL了。
因此,如果要考慮“.NET可否移植”這個(gè)命題,我想如果你從一開(kāi)始就考慮到框架的可移植性問(wèn)題,則它是成立的。但如果換個(gè)說(shuō)法“我有個(gè)使用.NET開(kāi)發(fā)的Windows應(yīng)用程序,它應(yīng)該可以在Mono上運(yùn)行”,那就不正確了——不過(guò)Mono讓移植這樣的應(yīng)用程序變得簡(jiǎn)單許多。
隨后Lloeki談?wù)摿怂墓ぷ鞣绞剑?/p>
除了技術(shù)方面的因素以外,關(guān)鍵還是在于編寫(xiě)代碼的方式。
無(wú)論是哪種跨平臺(tái)的應(yīng)用程序(例如Java,Python,Ruby……),如果在寫(xiě)代碼時(shí)不考慮可移植性,那么你應(yīng)該假設(shè)這些代碼可以直接跨平臺(tái)執(zhí)行的可能性為零(即使實(shí)際上這樣的可能性要高出許多)。你無(wú)法隨便拿到一個(gè)程序集就保證它能在Mono下正確執(zhí)行。
不過(guò)對(duì)于一個(gè)新項(xiàng)目(或是你可以輕易重構(gòu)的項(xiàng)目),選擇.NET/Mono作為可移植的方案之一則是明智的,不過(guò)對(duì)于跨平臺(tái)的代碼來(lái)說(shuō),你還是需要不斷地進(jìn)行測(cè)試。如果你使用持續(xù)集成,那么只要簡(jiǎn)單的創(chuàng)建一個(gè)Mono構(gòu)建的節(jié)點(diǎn)即可。只要養(yǎng)成良好的習(xí)慣(例如路徑的分隔符),很多問(wèn)題可以在開(kāi)發(fā)階段就解決掉,而絕大部分代碼只要使用單元測(cè)試以及其他一些常見(jiàn)的實(shí)踐方式,再加上一點(diǎn)點(diǎn)先期規(guī)劃就能得到很好的跨平臺(tái)性。剩下的,例如平臺(tái)相關(guān)的代碼(如P/Invoke),則可以通過(guò)封裝,為不同平臺(tái)提供針對(duì)性的實(shí)現(xiàn)。這樣產(chǎn)出的項(xiàng)目,幾乎不會(huì)付出額外的代價(jià)就能得到很好的移植性。
當(dāng)然,使用一個(gè)Mono中不存在或是不兼容的類(lèi)庫(kù)則另當(dāng)別論,不過(guò)就我的個(gè)人而言還沒(méi)有遇到這樣的情況。這些是我們?cè)诠ぷ髦袑?shí)際用到的做法,我可以放心的聲稱(chēng)“.NET+Mono”是跨平臺(tái)的解決方案。
對(duì)于Mono于.NET功能的支持程度,Robert和Michael談到:
我用過(guò)Mono,我認(rèn)為它就和其他開(kāi)源平臺(tái)一樣好,只不過(guò)不是微軟直接支持的而已。如果你能接受Clojure或Scala這樣的開(kāi)源項(xiàng)目,那么Mono也能讓你滿(mǎn)意。Mono對(duì)于.NET的支持程度可以參考Mono Roadmap頁(yè)面。Mono并不等同于.NET,它們有或多或少的區(qū)別,例如現(xiàn)在你還無(wú)法使用Entity Framework。
Mono不是.NET的移植品,有些技術(shù)是Mono不會(huì)或不打算實(shí)現(xiàn)的(如Workflow Foundation或WPF),此外它們還提供了微軟.NET外的其他一些技術(shù),例如SIMD擴(kuò)展。簡(jiǎn)單地說(shuō),Mono和微軟.NET是基于相同基礎(chǔ)——CIL和BCL——的兩個(gè)不同項(xiàng)目。
在討論中,Mono創(chuàng)建者M(jìn)iguel de Icaza給出了最為詳細(xì)的回應(yīng):
“.NET是否跨平臺(tái)”是一個(gè)模糊的說(shuō)法,無(wú)論是框架本身還是整體環(huán)境都在不斷改變。
簡(jiǎn)單地說(shuō),作為.NET的基礎(chǔ)架構(gòu),CLI標(biāo)準(zhǔn)是跨平臺(tái)的,但如果要在不同平臺(tái)上得到最好的體驗(yàn),則勢(shì)必要使用各自平臺(tái)上有針對(duì)性的API。CLI技術(shù)家族從來(lái)沒(méi)有試著要“一次編寫(xiě),到處執(zhí)行”,好比電話(huà)和大型機(jī)的區(qū)別實(shí)在是太大了。與其為不同平臺(tái)提供統(tǒng)一的API和運(yùn)行時(shí),不如各自平臺(tái)上的最佳體驗(yàn)提供最正確的工具。試想那些非Windows PC或Unix服務(wù)器的程序員,要知道如今已經(jīng)出現(xiàn)了游戲設(shè)備,移動(dòng)電話(huà),機(jī)頂盒,分布式集群等太多激動(dòng)人心的平臺(tái)。
微軟的.NET框架不是跨平臺(tái)的產(chǎn)品,它只能運(yùn)行在Windows上。其他系統(tǒng)上還有一些.NET框架的變體,例如Windows Phone 7,XBox 360和瀏覽器中的Silverlight,它們都有些許不同的配置(Profile)。
如今你已經(jīng)可以在各個(gè)主流的操作系統(tǒng),電話(huà),移動(dòng)設(shè)備,嵌入式系統(tǒng)或是服務(wù)器上使用基于.NET的技術(shù),以下是各種CLI實(shí)現(xiàn)的列表,雖不完整,但應(yīng)該可以覆蓋99%的情況:
- 基于x86和x86-64的計(jì)算機(jī):
- ARM計(jì)算機(jī):
- PowerPC計(jì)算機(jī):
- 在Linux,BSD或Unix操作系統(tǒng)上使用完整的Mono功能。
- 在嵌入式系統(tǒng)中使用Mono,如PS3,Wii。
- 在XBox36上運(yùn)行Compact Framework。
- S390, S390x, Itanium, SPARC計(jì)算機(jī):
- 完整的Mono支持
- 其他嵌入式操作系統(tǒng):
有時(shí)候相同的代碼很難四處運(yùn)行。例如XNA代碼不會(huì)在每個(gè)桌面上運(yùn)行,反之亦然。為了.NET不同的配置里運(yùn)行,你需要修改些許代碼。以下是我所了解的一些配置:
- .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擴(kuò)展配置(Silverlight和完整的.NET 4 API)
以上配置都有多多少少的不同,這不是壞事。每個(gè)配置的設(shè)計(jì)都適應(yīng)其平臺(tái),去除任何一個(gè)都是不明智的。例如,Silverlight API可以控制瀏覽器,這不關(guān)電話(huà)什么事;由于缺少合適的支持,XNA的著色功能對(duì)PC硬件也沒(méi)有多少意義。你越早認(rèn)識(shí)到.NET不是個(gè)將開(kāi)發(fā)人員綁定在特定硬件或平臺(tái)上的解決方案,就能越早成為更好的開(kāi)發(fā)人員。
這意味著,有些API或解決方案可以在多個(gè)平臺(tái)中使用,例如ASP.NET可以用在Windows,Linux,Solaris,MacOS X上,因?yàn)?NET和Mono都提供了這些API。同時(shí),ASP.NET則無(wú)法在某些微軟支持的平臺(tái)上使用,例如XBox或Windows 7,也不支持Mono的Wii和iPhone配置。
其他解決方案的本質(zhì)也是一樣的。要完整列出這些技術(shù)需要一張復(fù)雜的表格,我不知道如何在這里表現(xiàn)出來(lái),不過(guò)這里有個(gè)特定技術(shù)與特定平臺(tái)的列表:
核心運(yùn)行時(shí)引擎(所有平臺(tái)):
- Reflection.Emit支持:除WP7、CF、XBox、MonoTouch和PS3外的所有平臺(tái) 。
- 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上存在一些限制。
語(yǔ)言:
- C# 4:所有平臺(tái)。
- C# 編譯器即服務(wù):Linux、MacOS、Solaris、BSD及Android。
- F#、IronRuby及IronPython:除WP7、CF、Xbox、MonoTouch及PS3外的所有平臺(tái)。
服務(wù)器技術(shù):
- ASP.NET:Windows、Linux、MacOS、BSD及Solaris。
- ADO.NET:所有平臺(tái)
- LINQ to SQL:所有平臺(tái)
- Entity Framework:僅Windows
- XML核心技術(shù):所有平臺(tái)
- XML序列化:除WP7,CF和XBox外的所有平臺(tái)。
- LINQ to XML:所有平臺(tái)
- System.Json:Silverlight,Linux,MacOS,MonoTouch,MonoDroid(譯注:可移植到其他平臺(tái))
- 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技術(shù):
- 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
圖像類(lèi)庫(kù):
- GDI+:Windows、Linux、BSD及MacOS
- Quartz:MacOS X、iPhone及iPad
- Cairo:Windows、Linux、BSD、MacOS、iPhone、iPad、MacOS X、PS3及Wii
Mono類(lèi)庫(kù) - 跨平臺(tái),可以在.NET里使用,不過(guò)需要手動(dòng)編譯:
- C# 4編輯器及服務(wù)
- Cecil - CIL操作,工作流,CIL探測(cè),鏈接器
- RelaxNG類(lèi)庫(kù)
- Mono.Data.* 數(shù)據(jù)提供者
- 完整的System.Xaml(用于安裝程序,.NET沒(méi)有提供這個(gè)技術(shù))
MonoTouch為iPhone上運(yùn)行的Mono,MonoDroid為Andriod上運(yùn)行的Mono。PS3和Wii的移植只供索尼和任天堂認(rèn)證的開(kāi)發(fā)人員使用。
在討論中Miguel de Icaza還表示,IBM至少完成了兩個(gè)針對(duì)AIX的Mono移植,不過(guò)他們的移植團(tuán)隊(duì)沒(méi)有得到反饋其成果的許可。
NET技術(shù):討論:“Mono是個(gè)跨平臺(tái)的.NET”是否是個(gè)正確的說(shuō)法,轉(zhuǎn)載需保留來(lái)源!
鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請(qǐng)第一時(shí)間聯(lián)系我們修改或刪除,多謝。