C# 泛型 Generic
c# 泛型 generic
泛型(generic) 允許您延遲編寫類或方法中的編程元素的數據類型的規范,直到實際在程序中使用它的時候。換句話說,泛型允許您編寫一個可以與任何數據類型一起工作的類或方法。
您可以通過數據類型的替代參數編寫類或方法的規范。當編譯器遇到類的構造函數或方法的函數調用時,它會生成代碼來處理指定的數據類型。下面這個簡單的范例將有助于您理解這個概念:
using system; using system.collections.generic; namespace genericapplication { ? ? public class mygenericarray<t> ? ? { ? ? ? ? private t[] array; ? ? ? ? public mygenericarray(int size) ? ? ? ? { ? ? ? ? ? ? array = new t[size + 1]; ? ? ? ? } ? ? ? ? public t getitem(int index) ? ? ? ? { ? ? ? ? ? ? return array[index]; ? ? ? ? } ? ? ? ? public void setitem(int index, t value) ? ? ? ? { ? ? ? ? ? ? array[index] = value; ? ? ? ? } ? ? } ? ? ? ? ? ? ? ? class tester ? ? { ? ? ? ? static void main(string[] args) ? ? ? ? { ? ? ? ? ? ? // 聲明一個整型數組 ? ? ? ? ? ? mygenericarray<int> intarray = new mygenericarray<int>(5); ? ? ? ? ? ? // 設置值 ? ? ? ? ? ? for (int c = 0; c < 5; c++) ? ? ? ? ? ? { ? ? ? ? ? ? ? ? intarray.setitem(c, c*5); ? ? ? ? ? ? } ? ? ? ? ? ? // 獲取值 ? ? ? ? ? ? for (int c = 0; c < 5; c++) ? ? ? ? ? ? { ? ? ? ? ? ? ? ? console.write(intarray.getitem(c) + " "); ? ? ? ? ? ? } ? ? ? ? ? ? console.writeline(); ? ? ? ? ? ? // 聲明一個字符數組 ? ? ? ? ? ? mygenericarray<char> chararray = new mygenericarray<char>(5); ? ? ? ? ? ? // 設置值 ? ? ? ? ? ? for (int c = 0; c < 5; c++) ? ? ? ? ? ? { ? ? ? ? ? ? ? ? chararray.setitem(c, (char)(c+97)); ? ? ? ? ? ? } ? ? ? ? ? ? // 獲取值 ? ? ? ? ? ? for (int c = 0; c < 5; c++) ? ? ? ? ? ? { ? ? ? ? ? ? ? ? console.write(chararray.getitem(c) + " "); ? ? ? ? ? ? } ? ? ? ? ? ? console.writeline(); ? ? ? ? ? ? console.readkey(); ? ? ? ? } ? ? } }
當上面的代碼被編譯和執行時,它會產生下列結果:
0 5 10 15 20 a b c d e
1. 泛型(generic)的特性
使用泛型是一種增強程序功能的技術,具體表現在以下幾個方面:
- 它有助于您最大限度地重用代碼、保護類型的安全以及提高性能。
- 您可以創建泛型集合類。.net 框架類庫在 system.collections.generic 命名空間中包含了一些新的泛型集合類。您可以使用這些泛型集合類來替代 system.collections 中的集合類。
- 您可以創建自己的泛型接口、泛型類、泛型方法、泛型事件和泛型委托。
- 您可以對泛型類進行約束以訪問特定數據類型的方法。
- 關于泛型數據類型中使用的類型的信息可在運行時通過使用反射獲取。
2. 泛型(generic)方法
在上面的范例中,我們已經使用了泛型類,我們可以通過類型參數聲明泛型方法。下面的程序說明了這個概念:
using system; using system.collections.generic; namespace genericmethodappl { ? ? class program ? ? { ? ? ? ? static void swap<t>(ref t lhs, ref t rhs) ? ? ? ? { ? ? ? ? ? ? t temp; ? ? ? ? ? ? temp = lhs; ? ? ? ? ? ? lhs = rhs; ? ? ? ? ? ? rhs = temp; ? ? ? ? } ? ? ? ? static void main(string[] args) ? ? ? ? { ? ? ? ? ? ? int a, b; ? ? ? ? ? ? char c, d; ? ? ? ? ? ? a = 10; ? ? ? ? ? ? b = 20; ? ? ? ? ? ? c = 'i'; ? ? ? ? ? ? d = 'v'; ? ? ? ? ? ? // 在交換之前顯示值 ? ? ? ? ? ? console.writeline("int values before calling swap:"); ? ? ? ? ? ? console.writeline("a = {0}, b = {1}", a, b); ? ? ? ? ? ? console.writeline("char values before calling swap:"); ? ? ? ? ? ? console.writeline("c = {0}, d = {1}", c, d); ? ? ? ? ? ? // 調用 swap ? ? ? ? ? ? swap<int>(ref a, ref b); ? ? ? ? ? ? swap<char>(ref c, ref d); ? ? ? ? ? ? // 在交換之后顯示值 ? ? ? ? ? ? console.writeline("int values after calling swap:"); ? ? ? ? ? ? console.writeline("a = {0}, b = {1}", a, b); ? ? ? ? ? ? console.writeline("char values after calling swap:"); ? ? ? ? ? ? console.writeline("c = {0}, d = {1}", c, d); ? ? ? ? ? ? console.readkey(); ? ? ? ? } ? ? } }
當上面的代碼被編譯和執行時,它會產生下列結果:
int values before calling swap: a = 10, b = 20 char values before calling swap: c = i, d = v int values after calling swap: a = 20, b = 10 char values after calling swap: c = v, d = i
3. 泛型(generic)委托
您可以通過類型參數定義泛型委托。例如:
delegate t numberchanger<t>(t n);
下面的范例演示了委托的使用:
using system; using system.collections.generic; delegate t numberchanger<t>(t n); namespace genericdelegateappl { ? ? class testdelegate ? ? { ? ? ? ? static int num = 10; ? ? ? ? public static int addnum(int p) ? ? ? ? { ? ? ? ? ? ? num += p; ? ? ? ? ? ? return num; ? ? ? ? } ? ? ? ? public static int multnum(int q) ? ? ? ? { ? ? ? ? ? ? num *= q; ? ? ? ? ? ? return num; ? ? ? ? } ? ? ? ? public static int getnum() ? ? ? ? { ? ? ? ? ? ? return num; ? ? ? ? } ? ? ? ? static void main(string[] args) ? ? ? ? { ? ? ? ? ? ? // 創建委托范例 ? ? ? ? ? ? numberchanger<int> nc1 = new numberchanger<int>(addnum); ? ? ? ? ? ? numberchanger<int> nc2 = new numberchanger<int>(multnum); ? ? ? ? ? ? // 使用委托對象調用方法 ? ? ? ? ? ? nc1(25); ? ? ? ? ? ? console.writeline("value of num: {0}", getnum()); ? ? ? ? ? ? nc2(5); ? ? ? ? ? ? console.writeline("value of num: {0}", getnum()); ? ? ? ? ? ? console.readkey(); ? ? ? ? } ? ? } }
當上面的代碼被編譯和執行時,它會產生下列結果:
value of num: 35 value of num: 175