.NET Framework泛型

.NET Framework泛型是一個很強大的新特性,它為每一種對象生成一份單獨的代碼(也就是所謂的“實例化”),這一份量身頂做的代碼具有很高的效率,是強類型的,不需要運行期多態的支持和負擔,有了泛型,就不再需要Object類來參與實現一些通用類或方法了.

.NET Framework泛型的作用

在CLR(common language runtime)1.0中,當要創建一個靈活的類或方法,但該類或方法在編譯期問不知道使用什麼類,就必須以System.Object類為基礎進行處理,而Object類在編譯期間沒有類型安全性,又必須進行強制類型轉換.另外,給值類型使用Object類會有性能損失,這給程式開發帶來諸多不便.故在CLR 2.0(.NET 3.5基於CLR 2.0)中,提供了泛型.

通過使用泛型類型,可以根據需要,用特定的類型替換泛型類型,同時保證了類型安全性:如果某個類型不支持泛型類,編譯器就會報錯,以阻止程度發生運行期錯誤.正確使用泛型將大大提高代碼的靈活性,結合一個優秀的設計模式,可以顯著縮短開發時間.

泛型的優勢

安 全

C#是一個類型安全的語言,類型安全允許編譯器(可信賴的)捕獲潛在的錯誤,而不是在程式運行時才發現(不可信賴的).在CLR1.0中,當使用集合時,這種類型安全就失效了:由.NET類庫提供的集合類全是存儲基類型(Object)的,而.NET中所有的一切都繼承於Object,因此所有類型都可以放到一個集合中,這相當於根本就沒有了類型檢測.下面的代碼也正好說明了這個問題.

可以往ArrayList里添加任何類型,也能通過編譯,但是在接下來的使用中,由於字元串“test”和Object對象都不能轉換為值類型int,這會拋出運行期錯誤,類型不再安全 .

性 能

泛型的一個主要優點是性能.如果對值類型使用普通的集合類,在把值類型轉換為引用類型和把引用類型轉換成為值類型時,程式會進行裝箱和拆箱操作,性能損失比較大,操作疊代多次時尤其嚴重。而使用泛型能使程式在運行期間明確知道操作的對象的類型,可以減少拆箱和裝箱的操作。

重 用

泛型允許更好地重用代碼.泛型類可以只定義一次,用於不同的類型實例化,減少代碼量,如list<int>, List<string>,List<object>等等,且泛型可以在一種語言中定義,在另一種.NET語言中使用(如C#,VB.NET等).泛型編譯為II。(intermediate language)代碼時,是採用占位符來表示泛型類型,並用專有的IL指令支持泛型操作,所以用某個類型實例化泛型不會在IL代碼中複製這些類.為了說明,使用一個最簡單的泛型類class Test<T>{...},編譯運行後,使用Visual Studio自帶的IL反彙編程式打開生成的執行檔,定位到Test<T>類的構造函式,可以看到下面的代碼:

可以看出,泛型類使用了占位符“T”來表示這個泛型所支持的類型參數,並不會生成多份Test類以適應不同的傳人類型.

真正的泛型實例化工作以“on-demand”的方式發生在JIT(Just—in time)編譯時,CLR為所有類型參數為“引用類型”的泛型類產生同一份代碼;但是如果類型參數為“值類型”,對每一個不同的“值類型”,CLR將為其產生一份獨立的代碼.

常用泛型

可空類型

C#中的值類型必須包含一個值,而引用類型可以為空(null),但是讓值類型可空是非常有用的(配合資料庫使用).所以,.NET提供了泛型System.Nullable<T>可以使值類型具備可空的性質,其中類型參數T必須是不可以為null的類型.因為可空類型使用得非常頻繁,所以C#有一種特殊的語法,使用“?”運算符,用於定義這種類型的變數,如int7.

泛型集合

圖1 泛型集合類 圖1 泛型集合類

System.Collection.Generic命名空間下有大量泛型集合類_J,圖1列示了幾個比較常用的泛型,它們使用起來都十分方便,.NET已經為這些類提供了完善的成員函式與屬性.

泛型的繼承

圖2泛型繼承關係示例 圖2泛型繼承關係示例

.NET已有的泛型的功能已經比較完善,但是如果想在其基礎上增加自定義的操作,可以定義一個泛型類並繼承.NET已有的泛型,見圖2.

需要注意的是,如果某個類型在它所繼承的基類型中受到約束,該類型就不能“解除約束”.也就是說,類型參數丁在基類中使用受到了某約束S,則在子類中T必須受到至少與基類型相同的約束.

相關詞條

相關搜尋

熱門詞條

聯絡我們