C# 泛型的簡單講解和應用

來源:互聯網
上載者:User

標籤:str   參考型別   轉換   code   執行個體化   回收   這一   bsp   color   

泛型什麼是泛型

  泛型是 2.0 版 C# 語言和公用語言運行庫 (CLR) 中的一個新功能。泛型將型別參數的概念引入 .NET Framework,型別參數使得設計如下類和方法成為可能:這些類和方法將一個或多個類型的指定延遲到用戶端代碼聲明並執行個體化該類或方法的時候。例如,通過使用泛型型別參數 T,您可以編寫其他用戶端代碼能夠使用的單個類,而不致引入運行時強制轉換或裝箱操作的成本或風險

為什麼要使用泛型

我感覺泛型的最主要特點是減少了代碼的重用性,保護了型別安全,減少了拆裝箱的操作從而提高了效能

舉例說明

參考:http://www.blogjava.net/Jack2007/archive/2008/05/05/198566.html

我們在編寫程式時,經常遇到兩個模組的功能非常相似,只是一個是處理int資料,另一個是處理string資料,或者其他自訂的資料類型,但我們沒有辦法,只能分別寫多個方法處理每個資料類型,因為方法的參數類型不同。有沒有一種辦法,在方法中傳入通用的資料類型,這樣不就可以合并代碼了嗎?泛型的出現就是便可以輕鬆解決這個問題。

比如編寫一個處理int類型的棧
public class Stack    {        private int[] m_item;        public int Pop(){...}        public void Push(int item){...}        public Stack(int i)        {            this.m_item = new int[i];        }}

上面代碼啟動並執行很好,但是,當我們需要一個棧來儲存string類型時,該怎麼辦呢?很多人都會想到把上面的代碼複製一份,把int改成string不就行了。當然,這樣做本身是沒有任何問題的,但一個優秀的程式是不會這樣做的,因為他想到若以後再需要long、Node類型的棧該怎樣做呢?還要再複製嗎?優秀的程式員會想到用一個通用的資料類型object來實現這個棧:

object 類型通用的棧
 1 public class Stack 2     { 3         private object[] m_item; 4         public object Pop(){...} 5         public void Push(object item){...} 6         public Stack(int i) 7         { 8             this.m_item = new[i]; 9         }10     }

這個棧寫的不錯,他非常靈活,可以接收任何資料類型,可以說是一勞永逸。但全面地講,也不是沒有缺陷的,主要表現在:

當Stack處理實值型別時,會出現裝箱、折箱操作,這將在託管堆上分配和回收大量的變數,若資料量大,則效能損失非常嚴重。 
在處理參考型別時,雖然沒有裝箱和折箱操作,但將用到資料類型的強制轉換操作,增加處理器的負擔。 
在資料類型的強制轉換上還有更嚴重的問題(假設stack是Stack的一個執行個體):

1 Node1 x = new Node1();2 3             stack.Push(x);4 5          Node2 y = (Node2)stack.Pop();

上面的代碼在編譯時間是完全沒問題的,但由於Push了一個Node1類型的資料,但在Pop時卻要求轉換為Node2類型,這將出現程式運行時的類型轉換異常,但卻逃離了編譯器的檢查。

 

針對object類型棧的問題,我們引入泛型,他可以優雅地解決這些問題。泛型用用一個通過的資料類型T來代替object,在類執行個體化時指定T的類型,運行時(Runtime)自動編譯為本地代碼,運行效率和代碼品質都有很大提高,並且保證資料類型安全。

 

使用泛型實現這個棧

下面是用泛型來重寫上面的棧,用一個通用的資料類型T來作為一個預留位置,等待在執行個體化時用一個實際的類型來代替。讓我們來看看泛型的威力:

public class Stack<T>    {        private T[] m_item;        public T Pop(){...}        public void Push(T item){...}        public Stack(int i)        {            this.m_item = new T[i];        }}

類的寫法不變,只是引入了通用資料類型T就可以適用於任何資料類型,並且型別安全的。這個類的調用方法:

//執行個體化只能儲存int類型的類

Stack<int> a = new Stack<int>(100);

      a.Push(10);

      a.Push("8888"); //這一行編譯不通過,因為類a只接收int類型的資料

      int x = a.Pop();

 

//執行個體化只能儲存string類型的類

Stack<string> b = new Stack<string>(100);

b.Push(10);    //這一行編譯不通過,因為類b只接收string類型的資料

      b.Push("8888");

string y = b.Pop();

 

這個類和object實現的類有截然不同的區別:

1.       他是型別安全的。執行個體化了int類型的棧,就不能處理string類型的資料,其他資料類型也一樣。

2.       無需裝箱和折箱。這個類在執行個體化時,按照所傳入的資料類型產生本地代碼,本地代碼資料類型已確定,所以無需裝箱和折箱。

3.       無需類型轉換。

 

其它的用法,後期更新~~~~~

C# 泛型的簡單講解和應用

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.