托管代碼的優(yōu)點(diǎn)
Microsoft中間語(yǔ)言與Java字節(jié)代碼共享一種理念:它們都是一種低級(jí)語(yǔ)言,語(yǔ)法很簡(jiǎn)單(使用數(shù)字代碼,而不是文本代碼),可以非??焖俚剞D(zhuǎn)換為內(nèi)部機(jī)器碼。對(duì)于代碼來(lái)說(shuō),這種精心設(shè)計(jì)的通用語(yǔ)法,有很重要的優(yōu)點(diǎn)。
1. 平臺(tái)無(wú)關(guān)性
首先,這意味著包含字節(jié)代碼指令的同一文件可以放在任一平臺(tái)中,運(yùn)行時(shí)編譯過(guò)程的最后階段可以很容易完成,這樣代碼就可以運(yùn)行在該特定的平臺(tái)上。換言之,編譯為中間語(yǔ)言就可以獲得.NET平臺(tái)無(wú)關(guān)性,這與編譯為Java字節(jié)代碼就會(huì)得到Java平臺(tái)無(wú)關(guān)性是一樣的。
注意.NET的平臺(tái)無(wú)關(guān)性目前只是一種可能,因?yàn)樵诰帉?xiě)本書(shū)時(shí),.NET只能用于Windows平臺(tái),但人們正在積極準(zhǔn)備,使它可以用于其他平臺(tái)(參見(jiàn)Mono項(xiàng)目,它用于創(chuàng)建.NET的開(kāi)放源代碼的實(shí)現(xiàn),參見(jiàn)http://www.go-mono.com/)。
2. 提高性能
實(shí)際上,IL比Java字節(jié)代碼的作用還要大。IL總是即時(shí)編譯的(稱(chēng)為JIT編譯),而Java字節(jié)代碼常常是解釋性的,Java的一個(gè)缺點(diǎn)是,在運(yùn)行應(yīng)用程序時(shí),把Java字節(jié)代碼轉(zhuǎn)換為內(nèi)部可執(zhí)行代碼的過(guò)程會(huì)導(dǎo)致性能的損失(但在最近,Java在某些平臺(tái)上能進(jìn)行JIT編譯)。
JIT編譯器并不是把整個(gè)應(yīng)用程序一次編譯完(這樣會(huì)有很長(zhǎng)的啟動(dòng)時(shí)間),而是只編譯它調(diào)用的那部分代碼(這是其名稱(chēng)由來(lái))。代碼編譯過(guò)一次后,得到的內(nèi)部可執(zhí)行代碼就存儲(chǔ)起來(lái),直到退出該應(yīng)用程序?yàn)橹?,這樣在下次運(yùn)行這部分代碼時(shí),就不需要重新編譯了。Microsoft認(rèn)為這個(gè)過(guò)程要比一開(kāi)始就編譯整個(gè)應(yīng)用程序代碼的效率高得多,因?yàn)槿魏螒?yīng)用程序的大部分代碼實(shí)際上并不是在每次運(yùn)行過(guò)程中都執(zhí)行。使用JIT編譯器,從來(lái)都不會(huì)編譯這種代碼。
這解釋了為什么托管IL代碼的執(zhí)行幾乎和內(nèi)部機(jī)器代碼的執(zhí)行速度一樣快,但是并沒(méi)有說(shuō)明為什么Microsoft認(rèn)為這會(huì)提高性能。其原因是編譯過(guò)程的最后一部分是在運(yùn)行時(shí)進(jìn)行的,JIT編譯器確切地知道程序運(yùn)行在什么類(lèi)型的處理器上,利用該處理器提供的任何特性或特定的機(jī)器代碼指令來(lái)優(yōu)化最后的可執(zhí)行代碼。
傳統(tǒng)的編譯器會(huì)優(yōu)化代碼,但它們的優(yōu)化過(guò)程是獨(dú)立于代碼所運(yùn)行的特定處理器的。這是因?yàn)閭鹘y(tǒng)的編譯器是在發(fā)布軟件之前編譯為內(nèi)部機(jī)器可執(zhí)行的代碼。即編譯器不知道代碼所運(yùn)行的處理器類(lèi)型,例如該處理器是x86兼容處理器或Alpha處理器,這超出了基本操作的范圍。例如Visual Studio 6優(yōu)化了一臺(tái)一般的Pentium機(jī)器,所以它生成的代碼就不能利用Pentium III處理器的硬件特性。相反,JIT編譯器不僅可以進(jìn)行Visual Studio 6所能完成的優(yōu)化工作,還可以?xún)?yōu)化代碼所運(yùn)行的特定處理器。
3. 語(yǔ)言的互操作性
使用IL不僅支持平臺(tái)無(wú)關(guān)性,還支持語(yǔ)言的互操作性。簡(jiǎn)言之,就是能將任何一種語(yǔ)言編譯為中間代碼,編譯好的代碼可以與從其他語(yǔ)言編譯過(guò)來(lái)的代碼進(jìn)行交互操作。
那么除了C#之外,還有什么語(yǔ)言可以通過(guò).NET進(jìn)行交互操作呢?下面就簡(jiǎn)要討論其他常見(jiàn)語(yǔ)言如何與.NET交互操作。
(1) VB.NET
Visual Basic 6在升級(jí)到Visual Basic .NET時(shí),經(jīng)歷了一番脫胎換骨的變化。Visual Basic是在最近的幾年中演化的,其早期版本Visual Basic 6并不適合運(yùn)行.NET程序。例如,它與COM的高度集成,且只把事件處理程序作為源代碼顯示給開(kāi)發(fā)人員,大多數(shù)后臺(tái)代碼不能用作源代碼。另外,它不支持繼承,Visual Basic使用的標(biāo)準(zhǔn)數(shù)據(jù)類(lèi)型也與.NET不兼容。
Visual Basic 6已經(jīng)升級(jí)為Visual Basic .NET,對(duì)VB進(jìn)行的改變非常大,完全可以把Visual Basic .NET當(dāng)作是一種新語(yǔ)言?,F(xiàn)有的VB6代碼不能編譯為VB.NET代碼,把VB6程序轉(zhuǎn)換為VB.NET時(shí),需要對(duì)代碼進(jìn)行大量的改動(dòng),但大多數(shù)修改工作都可以由Visual Studio .NET(VS的升級(jí)版本,用于與.NET一起使用)自動(dòng)完成。如果要把一個(gè)VB6項(xiàng)目讀取到Visual Studio .NET中,Visual Studio .NET就會(huì)升級(jí)該項(xiàng)目,也就是說(shuō)把VB6源代碼重寫(xiě)為VB.NET源代碼。雖然這意味著其中的工作已大大減輕,但用戶(hù)仍需要檢查新的VB.NET代碼,以確保項(xiàng)目仍可正確工作,因?yàn)檫@種轉(zhuǎn)換并不十分完美。
這種語(yǔ)言升級(jí)的一個(gè)副作用是不能再把VB.NET編譯為內(nèi)部可執(zhí)行代碼了。VB.NET只編譯為中間語(yǔ)言,就像C#一樣。如果需要繼續(xù)使用VB6編寫(xiě)程序,就可以這么做,但生成的可執(zhí)行代碼會(huì)完全忽略.NET Framework,如果繼續(xù)把Visual Studio作為開(kāi)發(fā)環(huán)境,就需要安裝Visual Studio 6。
(2) Visual C++ .NET
Visual C++ 6有許多Microsoft對(duì)Windows的特定擴(kuò)展。通過(guò)Visual C++ .NET,又加入了更多的擴(kuò)展內(nèi)容,來(lái)支持.NET Framework?,F(xiàn)有的C++源代碼會(huì)繼續(xù)編譯為內(nèi)部可執(zhí)行代碼,不會(huì)有修改,但它會(huì)獨(dú)立于.NET運(yùn)行庫(kù)運(yùn)行。如果要讓C++代碼在.NET Framework中運(yùn)行,就要在代碼的開(kāi)頭添加下述命令:
#using <mscorlib.dll>
還要把標(biāo)記/clr傳遞給編譯器,編譯器假定要編譯托管代碼,因此會(huì)生成中間語(yǔ)言,而不是內(nèi)部機(jī)器碼。C++的一個(gè)有趣的問(wèn)題是在編譯托管代碼時(shí),編譯器可以生成包含內(nèi)嵌本機(jī)可執(zhí)行代碼的IL。這表示在C++代碼中可以把托管類(lèi)型和非托管類(lèi)型合并起來(lái),因此托管C++ 代碼:
class MyClass
{
定義了一個(gè)普通的C++類(lèi),而代碼:
__gc class MyClass
{
生成了一個(gè)托管類(lèi),就好像使用C#或VB.NET編寫(xiě)類(lèi)一樣。實(shí)際上,托管C++比C#更優(yōu)越的一點(diǎn)是可以在托管C++代碼中調(diào)用非托管C++類(lèi),而不必采用COM交互功能。
如果在托管類(lèi)型上試圖使用.NET不支持的特性(例如,模板或類(lèi)的多繼承),編譯器就會(huì)出現(xiàn)一個(gè)錯(cuò)誤。另外,在使用托管類(lèi)時(shí),還需要使用非標(biāo)準(zhǔn)的C++特性(例如上述代碼中的__gc關(guān)鍵字)。
因?yàn)镃++允許低級(jí)指針操作,C++編譯器不能生成可以通過(guò)CLR內(nèi)存類(lèi)型安全測(cè)試的代碼。如果CLR把代碼標(biāo)識(shí)為內(nèi)存類(lèi)型安全是非常重要的,就需要用其他一些語(yǔ)言編寫(xiě)源代碼,例如C# 或VB.NET。
(3) Visual J#
最新添加的語(yǔ)言是Visual J#。在.NET Framework 1.1版本推出之前,用戶(hù)必須下載相應(yīng)的軟件,才能使用J#?,F(xiàn)在J#語(yǔ)言?xún)?nèi)置于.NET Framework中。因此,J#用戶(hù)可以利用Visual Studio .NET的所有常見(jiàn)特性。Microsoft希望大多數(shù)J++用戶(hù)認(rèn)為他們?cè)谑褂?NET時(shí),將很容易使用J#。J#不使用Java運(yùn)行庫(kù),而是使用與其他.NET兼容語(yǔ)言一樣的基類(lèi)庫(kù)。這說(shuō)明,與C#和VB.NET一樣,可以使用J#創(chuàng)建ASP.NET Web應(yīng)用程序、Windows窗體、XML Web服務(wù)和其他應(yīng)用程序。
(4) 腳本語(yǔ)言
腳本語(yǔ)言仍在使用之中,但由于.NET的推出,一般認(rèn)為它們的重要性在降低。另一方面,JScript升級(jí)到JScript.NET。ASP.NET頁(yè)面可以用JScript.NET編寫(xiě),現(xiàn)在可以把JScript.NET當(dāng)作一種編譯語(yǔ)言來(lái)運(yùn)行,而不是解釋性的語(yǔ)言,也可以編寫(xiě)輸入量比較大的JScript.NET代碼。有了ASP.NET后,就沒(méi)有必要在服務(wù)器端的Web頁(yè)面上使用腳本語(yǔ)言了,但VBA仍用作Office文檔和Visual Studio宏語(yǔ)言。
(5) COM和COM+
從技術(shù)上講,COM 和 COM+并不是面向.NET的技術(shù),因?yàn)榛谒鼈兊慕M件不能編譯為IL(但如果原來(lái)的COM組件是用C++編寫(xiě)的,使用托管C++,在某種程度上可以這么做)。但是,COM+仍然是一個(gè)重要的工具,因?yàn)槠涮匦詻](méi)有在.NET中完全實(shí)現(xiàn)。另外,COM組件仍可以使用——.NET組合了COM的互操作性,從而使托管代碼可以調(diào)用COM組件,COM組件也可以調(diào)用托管代碼(見(jiàn)第29章)。在大多數(shù)情況中,把新組件編寫(xiě)為.NET組件,其多數(shù)目的是為了比較方便,因?yàn)檫@樣可以利用.NET基類(lèi)和托管代碼的其他優(yōu)點(diǎn)。
點(diǎn)擊加載更多評(píng)論>>