最近頻繁的接觸到泛型方面的問題,所以也不得不來學習一下了,開始主要是在MSDN的WebCast上去下載教學錄象看的(李建忠老師的),本篇文章先介紹一下泛型入門方面的知識,希望能讓剛開始學習泛型的朋友能夠更快的入門,言歸正傳,首先我們來看一下泛型的基本概念。
最顯著的一點就是它參數化了類型,把類型作為參數抽象出來,從而使我們在實際的運用當中能夠更好的實現代碼的重復利用,同時它提供了更強的類型安全,更高的效率,不過在約束方面,它只支持顯示的約束,這樣在靈活性方面就顯得不是那麼好了。我覺得它之所以能夠提供更高的效率是因為泛型在實例化的時候采用了"on-demand"的模式,即按需實例化,發生在JIT(Just In Time)編譯時。
下面來看如何定義一個泛型類,很簡單,你只需要意識到一點,在這裡,類型已經被參數化了:
using System; using System.Collections.Generic; using System.Text; namespace GenericTest { class Program { static void Main(string[] args) { //使用string,int來實例化Test<T,S>類 Test<string, int> t = new Test<string, int>("SHY520",22); //調用泛型類中的方法 t.SetValue(); } } /**//// <summary> /// 定義一個泛型類,該類有兩個類型參數,分別是T,S /// http://pw.cnblogs.com /// </summary> /// <typeparam name="T">類型參數</typeparam> /// <typeparam name="S">類型參數</typeparam> public class Test<T,S> { //泛型類的類型參數可用於類成員 private T name; private S age; public Test(T Name,S Age) { this.name = Name; this.age = Age; } public void SetValue() { Console.WriteLine(name.ToString()); Console.WriteLine(age.ToString()); } } }
上面的例子不是很恰當,目的是讓初學泛型的你了解一下泛型的定義及實例化方法,如上,我們定義了一個泛型類,那麼如何實現泛型類的繼承呢?這裡需要滿足下面兩點中的任何一點即可:
1、泛型類繼承中,父類的類型參數已被實例化,這種情況下子類不一定必須是泛型類;
2、父類的類型參數沒有被實例化,但來源於子類,也就是說父類和子類都是泛型類,並且二者有相同的類型參數;
//如果這樣寫的話,顯然會報找不到類型T,S的錯誤 public class TestChild : Test<T, S> { } //正確的寫法應該是 public class TestChild : Test<string, int>{ } public class TestChild<T, S> : Test<T, S> { } public class TestChild<T, S> : Test<String, int> { }
接著我們來看看泛型接口,其創建以及繼承規則和上面說的泛型類是一樣的,看下面的代碼:
public interface IList<T> { T[] GetElements(); } public interface IDictionary<K,V> { void Add(K key, V value); } // 泛型接口的類型參數要麼已實例化 // 要麼來源於實現類聲明的類型參數 class List<T> : IList<T>, IDictionary<int, T> { public T[] GetElements() { return null; } public void Add(int index, T value) {} }
在來看一下泛型委托,首先我們定義一個類型參數為T的委托,然後在類中利用委托調用方法:
using System; using System.Collections.Generic; using System.Text; namespace GenericTest { //定義一個委托,類型參數為T,返回值類型T //泛型委托支持在返回值和參數上應用類型參數 delegate string GenericDelete<T>(T value); class test { static string F(int i) { return "SHY520"; } static string G(string s) { return "SHY520"; } static void Main(string[] args) { GenericDelete<string> G1 = G; GenericDelete<int> G2 = new GenericDelete<int>(F); } } }
我們再來看泛型方法,C#的泛型機制只支持在方法申明上包含類型參數,也即是泛型方法。特別注意的是,泛型不支持在除了方法以外的其他類/接口成員上使用類型參數,但這些成員可以被包含在泛型類型中,並且可以使用泛型類型的類型參數。還有一點需要說的就是,泛型方法可以在泛型類型中,也可以存在於非泛型類型中。下面我們分別看一下泛型類型的申明,調用,重載和覆蓋。