全面介紹C#面向?qū)ο蟮确矫?/h1>
C#面向?qū)ο?/STRONG>
C#面向?qū)ο蠊δ艿闹С智闆r, C#當(dāng)然支持所有關(guān)鍵的面向?qū)ο蟮母拍?,如封裝、繼承和多態(tài)性。完整的C#類模式構(gòu)建在NGWS運(yùn)行時(shí)的虛擬對(duì)象系統(tǒng)(VOS,Virtual Object System)的上層,VOS將在下章描述。對(duì)象模式只是基礎(chǔ)的一部分,不再是編程語言的一部分。您一開始必須關(guān)注的事,就是不再有全局函數(shù)、變量或者是常量。所有的東西都封裝在類中,包括事例成員(通過類的事例——對(duì)象可以訪問)或都靜態(tài)成員(通過數(shù)據(jù)類型)。這些使C#代碼更加易讀且有助于減少潛在的命名沖突。定義類中的 方法默認(rèn)是非虛擬的(它們不能被派生類改寫)。主要論點(diǎn)是,這樣會(huì)消除由于偶爾改寫方法而導(dǎo)致另外一些原碼出錯(cuò)。要改寫方法,必須具有顯式的虛擬標(biāo)志。 這種行為不但縮減速了虛擬函數(shù)表,而且還確保正確版本的控制。
使用C++編寫類,您可以使用訪問權(quán)限(access modifiers) 給類成員設(shè)置不同的訪問等級(jí)。C#同樣支持private、protected 和public 三種訪問權(quán)限 ,而且還增加了第四種:internal.有關(guān)訪問權(quán)限 的詳細(xì)情況將在第五章 "類" 中說明。
您曾經(jīng)創(chuàng)建了多少個(gè)類是從多基類派生出來的(ATL 程序員,您的投票不計(jì)在內(nèi)?。?? 大多數(shù)情況,僅需從一個(gè)類派生出。多基類惹出的麻煩通常比它們解決的問題還多。那就是為什么C#僅允許一個(gè)基類。如果您覺得需要多重繼承,可以運(yùn)用接口。
一個(gè)可能出現(xiàn)的問題:在C#中不存在指針,如何模仿它? 這個(gè)問題的答案很有代表性,它提供了對(duì)NGWS運(yùn)行時(shí)事件模式的支持。再次,我將把對(duì)它的全面解釋放到第五章。
類型安全
我再次選指針作為一個(gè)例子。在C++中擁有一個(gè)指針,您能自由地把它強(qiáng)制轉(zhuǎn)換成為任何類型,包括干出諸如把一個(gè)int*(整型指針)強(qiáng)制轉(zhuǎn)換成一個(gè)double *(雙精度指針)這樣的傻事。只要內(nèi)存支持這種操作,它就"干過".這并不是您所想象的企業(yè)級(jí)編程語言的類型安全。
綱要性的問題,C#實(shí)施最嚴(yán)格的類型安全,以保護(hù)自己及垃圾收集器(garbage collector)。所以必須遵守C#中一些相關(guān)
變量的規(guī)則:您不能使用沒有初始化的變量。對(duì)于對(duì)象的成員變量,編譯器負(fù)責(zé)清零。而局部變量,則由您負(fù)責(zé)清零。當(dāng)您使用一個(gè)沒有初始化的變量時(shí),編譯器會(huì)教您怎么做。優(yōu)點(diǎn)是能夠避免由于使用不經(jīng)初始化的變量計(jì)算結(jié)果而導(dǎo)致的錯(cuò)誤,而您還不知道這些奇怪的結(jié)果是如何產(chǎn)生的。
C#取消了不安全的類型轉(zhuǎn)換。不能把一個(gè)整型強(qiáng)制轉(zhuǎn)換成一個(gè)引用類型(如對(duì)象),而當(dāng)向下轉(zhuǎn)換時(shí),C#驗(yàn)證這種轉(zhuǎn)換是正確的。(也就是說,派生類真的是從向下轉(zhuǎn)換的那個(gè)類派生出來的。)邊界檢查是C#的一部分。再也不會(huì)出現(xiàn)這種情況:當(dāng)數(shù)組實(shí)際只定義了n-1個(gè)元素,卻超額地使用了n個(gè)元素。算術(shù)運(yùn)算有可能溢出終值數(shù)據(jù)類型的范圍。C#允許在語句級(jí)或應(yīng)用程序級(jí)檢測(cè)這些運(yùn)算。在允許檢測(cè)溢出的情況下,當(dāng)溢出發(fā)生時(shí)將會(huì)拋出一個(gè)異常。在C#中,被傳遞的引用參數(shù)是類型安全的。
版本可控(versionable)
在過去的幾年中,幾乎所有的程序員都至少有一次不得不涉及到眾所周知的"DLL地獄".該問題起因于多個(gè)應(yīng)用程序都安裝了相同DLL名字的不同版本。有時(shí),老版本的應(yīng)用程序可以很好地和新版本的DLL一起工作,但是更多的時(shí)候它們會(huì)中斷運(yùn)行?,F(xiàn)在的版本問題真是令人頭痛。就象您將在第八章"用C#寫組件"所看到的,NGWS runtime 將對(duì)您所寫的應(yīng)用程序提供版本支持。C#可以最好地支持版本控制。盡管C#不能確保正確的版本控制,但是它可以為程序員保證版本控制成為可能。有這種支持,一個(gè)開發(fā)人員就可以確
保當(dāng)他的類庫升級(jí)時(shí),仍保留著對(duì)已存在的客戶應(yīng)用程序的二進(jìn)制兼容。
兼容
C#并沒有存在于一個(gè)封閉的世界中。它允許使用最先進(jìn)的NGWS的通用語言規(guī)定(Common Language Specification,簡(jiǎn)寫為CLS)訪問不同的API.CLS規(guī)定了一個(gè)標(biāo)準(zhǔn),用于符合這種標(biāo)準(zhǔn)的語言的內(nèi)部之間的操作。為了加強(qiáng)CLS的編譯,C#編譯器檢測(cè)所有的公共出口編譯,并在通不過時(shí)列出錯(cuò)誤。
當(dāng)然,您也想能夠訪問舊一點(diǎn)的COM對(duì)象。NGWS運(yùn)行時(shí)提供對(duì)COM透明的訪問。如何集成原來的代碼將在后面章節(jié)"非管理代碼的內(nèi)部操作"有介紹。
OLE 自動(dòng)化是一種特殊的動(dòng)物。任一個(gè)使用C++創(chuàng)建OLE自動(dòng)化項(xiàng)目的人已經(jīng)喜歡上各種各樣的自動(dòng)化數(shù)據(jù)類型。有個(gè)好消息就是C#支持它們,而沒有煩鎖的細(xì)節(jié)。
最后,C#允許您用C原型的API進(jìn)持內(nèi)部操作??梢詮哪膽?yīng)用程序訪問任何DLL中的入口點(diǎn)(有C的原型) .用于訪問原始API的功能稱作平臺(tái)調(diào)用服務(wù)(Plaform Invocation Services ,縮寫PInovke) .
靈活
上一部分的最后一段有可能提醒了程序員。您可能會(huì)問:"難道就沒有我要傳遞指針的API嗎?" 您是正確的。不是僅有少數(shù)的這種API,而是很多(有點(diǎn)保守的估計(jì))。這種對(duì)原始WIN32代碼的訪問有時(shí)導(dǎo)致對(duì)非安全類指定指針的使用(盡管它們中的一些由于受COM和PInvoke的支持可以解決)。
盡管C#代碼的缺省狀態(tài)是類型安全的,但是您可以聲明一些類或者僅聲明類的的方法是非安全類型的。這樣的聲明允許您使用指針、結(jié)構(gòu),靜態(tài)地分配數(shù)組。安全碼和非安全碼都運(yùn)行在同一個(gè)管理空間,這樣暗示著當(dāng)從安全碼調(diào)用非安全碼時(shí)不會(huì)陷入列集(marshaling)。
小結(jié)
C#語言從C和C++演變而來,它是給那些愿意犧牲C++一點(diǎn)底層功能,以獲得更方便和更產(chǎn)品化的企業(yè)開發(fā)人員而創(chuàng)造的。C#面向?qū)ο蠛皖愋桶踩1M管它借鑒了C和C++的許多東西,但是在一些諸如名字空間、類、方法和異常處理等
特定領(lǐng)域,它們之間還存在著巨大的差異。C#為您提供了方便的功能,如垃圾收集、類型安全、版本控制,等等。僅有的"代價(jià)"就是,代碼操作默認(rèn)是類型安全的,不允許指針。光是類型安全就可以搞定了。但是,如果您需要指針,仍可以通過非安全碼使用它們,而且當(dāng)調(diào)用非安全碼時(shí),不能含有列集。
【編輯推薦】