dotNET下的泛型編程

dotNET下的泛型編程

1、什麼是泛型編程(generic programming)?

即通用的程式設計。什麼是通用的程式設計呢?學數據結構的都知道,存在一個這樣的公式:

      程序 = 算法 + 數據結構

這個經典的公式簡單地描述了一個程序的由來,即使您的程序有多麼的複雜。在OOP還沒有出現之前,算法和數據結構所佔的份量幾乎是同等的。C語言就是一個這樣的主導的開發模式。

而泛型呢?則把算法放在主導位置,中間忽略了大量的數據結構中存在的差異產生的分岐。而我們完全可以把所有時間和精力主要集中在研究算法上,而不會爲了支持各種各樣的數據結構,而導致做大量的無意義的低效的工作了。這是一種very smart的開發模式!也是比較科學的解決方案(會心一笑)。在以後的編程中,我們應該不斷的提倡使用泛型,主要把時間集中在算法的研究及改進,提供最有效的算法,目的是爲了開發最好的軟件給用戶。用戶的放心,也是我們的開心。


2、泛型如何實施?

2.1 哪些程式設計語言支持泛型?

比如說我們要寫一個Array類,要讓它支持所有的內置類型(int/string/double etc...),一般的程序員,可能會想到爲每一種內置類型都編寫一個同樣的類(天哪!羅馬工程!),稍聰明一點的,會想到把相同的代碼提出來封裝成一個個函數供調用(這樣做也會導致代碼閱讀困難,因爲call太多了,跟蹤的工程浩大,並且函數的調用也會相應地犧牲一些系統性能);而通常C語言的高手可能會採用指針或是union來做(容易出錯及較低級,實施困難);而有OO概念的,可能就會考慮採用“祖先類”來設計(也容易出錯及在類型轉換時會導致系統性能下降,而dotNET則會產生裝箱和拆箱的冗餘操作);那些都是在不支持泛型的語言下的唯一方案,你別無選擇。

很幸運地,聰明的編譯器製造者給我們帶來了泛型編程!哪些語言支持泛型呢?由於在下才舒學淺,只會MASM32/C/C++/VB/C#/VB.NET。在那幾種最新版本的語言中,C++和dotNET都相應有了泛型的支持。C++有template(模板),功能強大!本人的最愛;而dotNET也不甘落後,比爾給我們帶來了System.Collections.Generic名字空間。

在這裏,我們要講的是dotNET下的泛型編程。C++在本人的BLOG中,也有相應的template文章。不過我還是推薦大家看《C++Primer》,這是一本巨好的書!簡直就是C++中的鬼斧神工聖經級書籍。選擇什麼版本呢?當然,英文好的讀原版,而後者則推薦“潘愛民和張麗”翻譯的版本。翻譯的質量你不用懷疑,錯誤極少,措辭也極優美,閱讀很暢通,總之質量很高,雖然有小許瑕疵,不過那些可能是原版所造成的吧?本人只發現P144中,名字空間域操作符“::”漏了一個冒號。


2.2 由object類型(dotNET的祖先類)所構成的通用程式設計

回顧object類型,它支持以下行爲:

1)object可以來引用任何類型的實例;
2)object類型可以存儲任何類型的值(簡單類型就是一個值,複雜的就是一個指針);
3)可以定義object類型的參數;
4)可以把object作爲返回類型。

絕大多數從C/VB/DELPHI等語言轉過來的dotNET程序員,一般都是用object類型來編寫通用的程序方法。當然,object用來編寫這種框架,既簡單又方便,但是卻因此,會引來裝箱和拆箱的操作及類型轉換所造成的系統開銷,這在實施大型系統時,是我們最不想看到的結果。


2.3 .NET Framework 2.0 中的泛型設計

2.3.1 泛型的引入

終於,在Framework 2.0中,一些喜愛C++的Microsoft的工程師給我們帶來了和C++差不多的泛型設計。這是非常可喜可賀的。這個主要的目的就是爲了避免在強制類型轉換,及減少裝箱拆箱提高性能,減少錯誤。

System.Collections.Generic命名空間提供許多集合類和接口的泛型版本:有泛型類,泛型接口,泛型方法,泛型委託。在這裏我們只介紹泛型類和泛型方法。泛型接口可參考泛型類,泛型委託參考泛型方法。都很簡單。

2.3.2 泛型類(C++中叫類模板)

2.3.2.1 定義

要定義一個泛型類很簡單,只要在類名稱的後面加上由一對尖括號構成的參數列表就行了。如下所示:
 
public class GenericList
{
    public void Add(T input); // T 制定成類型參數
    public T Add();  // T 制定成返回值
}

解釋:的T是類型參數,起佔位符的作用,編譯時被真正類型取代。

另,參數列表支持多個參數。如下:
public class 類名

2.3.2.2 約束

確保泛型類使用的參數是提供特定方法的類型。

public class GenericList where T : IEmployee

假如IEmployee接口包含A方法,編譯器會驗證用於替換T的類型一定要實現IEmployee接口。

2.3.2.3 用法

使用泛型類很簡單,只要在類名稱的後面加上由一對尖括號構成的實參列表就行了。如下:

GenericList list1 = new GenericList();
GenericList list2 = new GenericList();
GenericList<類名> list3 = new GenericList<類名>();
GenericList<類名> list4= new GenericList<類名>();


2.3.3 泛型方法(泛型函數。C++中叫函數模板)

2.3.3.1 定義

//定義泛型方法
static void Swap(ref T lhs, ref T rhs)
{
   T temp;
   temp = lhs;
   lhs = rhs;
   rhs = temp;
}

2.3.3.2 用法

//使用泛型方法
public static void TestSwap()
{
   int a = 1;
   int b = 3;
   Swap(ref a, ref b);

   string s1 = "Hello";
   string s2 = "world";
   Swap(ref s1, ref s2);
}

最後,希望和大家一起共同進步。我的email: [email protected]和您深入討論MASM32/C++/C#。


 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章