C#中的泛型-1

快看一隻熊發表於2014-05-16

    在軟體這個行業,做的越久,往往會覺得很多技術問題最終會偏向資料結構和演算法。

    記得曾經大學的一堂課上,老師講了一個關於氣泡排序的演算法,下面是課本上的標準實現。

 1 public class Sort
 2      {
 3          public void sortArray(int[] arry)
 4          {
 5              int length = arry.Length;
 6              for (int i = 0; i <= length - 2; i++)
 7              {
 8                  for (int j = length - 1; j >= 1; j--)
 9                  {
10                      if (arry[j]<arry[j - 1])
11                      {
12                          int temp = arry[j];
13                          arry[j] = arry[j - 1];
14                          arry[j - 1] = temp;
15                      }
16                  }
17              }
18          }
19      }

    當然,就排序本身不是我們這裡要討論的問題。上面的程式碼實現了一個功能:將一組陣列元素按照從大到小的順序排列。
    進行簡單的測試

 1 static void Main(string[] args)
 2         {
 3             Sort sor = new Sort();
 4             //建立一個int陣列
 5             int[] array = { 8,1,4,7,3};
 6             //排序
 7             sor.sortArray(array);
 8             //列印排序結果
 9             foreach (int i in array)
10             {
11                 Console.WriteLine("{0} : ",i);
12             }
13             Console.ReadLine();
14         }

得到的結果是:
1  3  4  7  8

    發現結果ok,心想這就是完美的了。但是不久之後,又需要對一個byte陣列進行排序,而這個程式只接受int型引數,儘管byte的資料範圍是int的子集,但是強型別的C#語言不允許我們在一個接受int的地方傳入byte,不過沒關係,靈機一動,把上面程式碼複製一邊,引數改為byte[]不久好了。

 

 1 public class Sort
 2      {
 3          public void sortArray(byte[] arry)
 4          {
 5              int length = arry.Length;
 6              for (int i = 0; i <= length - 2; i++)
 7              {
 8                  for (int j = length - 1; j >= 1; j--)
 9                  {
10                      if (arry[j] < arry[j - 1])
11                      {
12                          byte temp = arry[j];
13                          arry[j] = arry[j - 1];
14                          arry[j - 1] = temp;
15                      }
16                  }
17              }
18          }
19      }

    以往寫程式碼首先是要實現功能,功能實現了,下一步才是討論如何優化。因為設計之處,大家能夠想到很多很多可能面臨的問題,但實際上有些問題可能永遠不會發生,你卻花費了大量的時間。我囉嗦這句話的意思其實是想告訴大家,不要過早的進行抽象化和應對變化。上面兩個方法已經很好的解決了int和byte的問題,但是新的需求又來了,這一次需要對char型別的陣列進行排序。當然可以繼續copy上面的方法,可是似乎聰明的人不能接受,我們要善於總結歸納,這是曾經上學時我認為學習數學和物理最重要的方法。
    對比前面兩個方法,它們除了方法的簽名不同之外完全是一樣的,曾經開發web的時候,在web上生成靜態頁面最常用的一個方式是使用模版,每次生成靜態頁面的時候先載入模版,模版中含有特殊的佔位符,然後從資料庫讀取資料,使用取出的資料替換這些佔位符,最後將模版按照一定的命名規範生成HTML靜態檔案儲存在伺服器上,所以伺服器無需重寫url,只需要把靜態檔案返回給客戶端就好了。

    基於這種思路,我們上面的方法可以視為一個模版,而int[],byte[]的位置就使用佔位符來替換掉好了。

    於是,把int,byte,char等等都看作是->T,T代表所有型別。

    這個時候方法的簽名就是下面這樣了:

 public void sort(T[] arry)
 

    但是又有問題了,T怎麼知道自己是誰呢?int,byte還是其他?有人可能想到,通過類的構造方法傳遞T的型別,這裡要說明的是,構造方法接受的引數是型別的例項,而T本身就是型別,顯然無法傳遞它。

public Sort(型別的例項);

    .NET專門定義了一種型別傳遞方式

1 public class SortHelper<T>      {
2          public void sort(T[] arry)
3          {
4              ......
5           }
6      }

    使用方法:

1 Sort<byte> sort  = new Sort<byte>();
2 byte[] array = {8,1,4,7,3};
3 sort.sortArray(array);

    此時,T知道自己是byte了,但是編譯後發現錯誤,這是下一次要討論的問題~

 

相關文章