CLR via C 深解筆記六 泛型

2022-02-14 12:03:08 字數 2143 閱讀 8889

物件導向程式設計乙個好處就是「**重用」,極大提高了開發效率。如是,可以派生出乙個類,讓它繼承基類的所有能力,派生類只需要重寫虛方法,或新增一些新的方法,就可以定製派生類的行為,使之滿足開發人員的需求。

泛型(generic)是clr和程式語言提供的一種特殊機制,它支援另一種形式的**重用,即「演算法重用」。

簡單地說,開發人員先定義好乙個演算法,比如排序、搜尋、交換、比較或轉換等。但是,定義演算法的開發人員並不設定該演算法要操作什麼資料型別;該演算法可以廣泛地應用於不同型別的物件。然後,另乙個開發人員只要指定了演算法要操作的具體資料型別,就可以使用這個現成的演算法了。例如,可用乙個排序演算法來操作int32和string等型別的物件,或用乙個比較演算法來操作datetime和version等型別的物件。大多數演算法都封裝在乙個型別中,clr允許建立泛型引用型別和泛型值型別,但不允許建立泛型列舉型別。還允許建立泛型介面和泛型委託。

泛型為開發人員提供了一下優勢:

#1,源**保護。

#2,型別安全。編譯器和clr能理解開發人員的意圖,並保證只有與指定資料型別相容的物件才能隨同演算法使用。

#3,更加清晰的**。減少了源**中必須進行的轉型次數,**更容易編寫和維護。

#4,更佳的效能。建立泛型演算法來操作一種具體的值型別,所以值型別的例項能夠以傳值方式傳遞,clr不再需要執行任何裝箱操作。arraylist來操作值型別(如int32),會造成大量裝箱操作,大量的垃圾**。

泛型最明顯的應用就是集合類。fcl已經定義了幾個泛型集合類,其中,大多數類都在system.collections.generic 和system.collections.objectmodel命名空間中。

泛型基礎結構

開發型別和封閉型別

我們關注clr如何為應用程式使用的每個型別建立乙個怎樣的內部資料結構,這種資料結構稱為型別物件(type object)。具有泛型型別引數的型別仍然是型別,clr同樣會為它建立乙個內部型別物件。無論引用型別(類)、值型別(結構)、介面型別,還是委託型別,這一點都成立。具有泛型型別引數的型別稱為開放型別(open type), clr禁止構造開發型別的任何例項,類似clr禁止構造介面型別的例項, 如list<>。

**引用乙個泛型型別時,可指定一組泛型型別實參。假如為所有型別實參傳遞的都是實際資料型別,型別就稱為封閉型別(closed type),clr允許構造封閉型別的例項,如list。需要注意的是,clr會在型別物件內部分配型別的靜態字段,因此每個封閉型別都有自己的靜態字段。例如,list定義了任何靜態字段,都不會在乙個list和乙個list之間共享:每個封閉型別物件都有它自己的靜態字段。假如乙個泛型型別定義了乙個靜態構造器,那麼針對每個封閉型別,這個構造器都會執行一次。在泛型型別上定義乙個靜態構造器的目的是保證傳遞的型別實參滿足特定的條件(約束)。如,希望乙個泛型型別只用於處理列舉型別,就可以如下定義:

internal sealed class generictypethatrequiresanenum}}

clr提供了乙個名為約束的功能,可利用它更好地定義乙個泛型型別來支出哪些型別實參是有效的。

****

使用泛型型別引數的乙個方法在進行jit編譯時,clr獲取方法的il,用指定的型別實參進行替換,然後建立恰當的本地**(這些**是為操作指定資料型別的方法「量身定製」的)。這樣做有乙個缺點:clr要為每一種不同的方法/型別組合生成本地**。這個現象稱為****(code explosion)。它可能造成應用程式的工作集顯著增大,從而損害效能。

clr還提供了另乙個優化措施,它認為所有引用型別實參都是完全相同的,所以**可以共享。如,clr為list的方法編譯的**可直接用於list的方法,因為string和stream均為引用型別。事實上,對於任何引用型別,都會使用相同的**。clr之所以能執行這個優化,是因為所有引用型別的實參或變數實際只是指向堆上的物件的指標,而物件指標全部是以相同的方式來操作的。

但是,某個型別實參是值型別,clr就必須專門為這個值型別生成本地**,因為值型別的大小不定,還可能要用不同的本地cpu指令來操縱這些值。

委託和介面的逆變和協變泛型型別實參

CLR via C 深解筆記五 事件

事件處理實際上是一種具有特殊簽名的delegate,像這個樣子 public delegate void eventhandler object sender,eventargs e 型別定義事件成員,就可以通知其他物件發生了特定的事情。如果定義乙個事件成員,意味著型別要提供一下能力 1,方法可登記...

CLR via C 泛型 FCL中的泛型

泛型最明顯的應用就是集合類。fcl在system.collections.generic和system.collections.objectmodel命名空間中提供了多個泛型集合類。system.collections.concurrent命名空間則提供了執行緒安全的泛型集合類。microsoft建...

Clr via C 讀書筆記 Cp12泛型

generic system.collections.generic 開放型別,封閉型別 每個封閉型別都有自己的靜態成員 新的型別派生自泛型型別派生的那個類 實參指定和派生層次沒有關係 使用using和區域性隱式型別來解決 了解就可以了 擁有泛型的那些好處 類似泛型介面 不變數 泛型型別引數不能更改...