一开始我觉着这本书太厚了,直到看到泛型这一章,发现这本书真不够,毕竟要把一个复杂的概念讲透,没一定的篇幅是不可能的。
泛型这个概念困扰我很久了,所以我把这章翻来覆去看了好几遍,又去网上找了一些文章,算是搞明白了。
先看看泛型的概念:“通过参数化类型来实现在同一份代码上操作多种数据类型。利用“参数化类型”将类型抽象化,从而实现灵活的复用”。所以,有了泛型,就可以创建独立于被包含类型的类和方法了。不必给不同的类型编写功能相同的许多方法或类,只创建一个方法或类即可。
废话少说,来看代码:
1,不用泛型的后果
我们创建一个方法对int数组进行排序,算法是冒泡:
public class SortHelper { public void BubbleSort(int[] arr) { int length = arr.Length; for (int i = 0; i < length-1; i++) { for (int j = 0; j < length-1-i; j++) { if (arr[j]>arr[j+1]) { int temp=arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; } } } } }
测试:
static void Main(string[] args) { SortHelper sorter = new SortHelper(); int[] a = { 4,5,1,3,2,8,5,0,2}; sorter.BubbleSort(a); //输出省略 }
输出为:0,1,2,2,3,4,5,5,8
如果数组是Byte类型的呢,简单,直接复制方法,改改签名就完事了
public class SortHelper { public void BubbleSort(byte[] arr) { int length = arr.Length; for (int i = 0; i < length-1; i++) { for (int j = 0; j < length-1-i; j++) { if (arr[j]>arr[j+1]) { byte temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; } } } } }
如果再引入其他数据类型的方法呢,那这个类就没法看了,长不说,维护起来也很麻烦,如果我想把冒泡改为快排,那每个方法都要改,那怎么办呢,这个时候就可以引入泛型。
2,使用泛型
简而言之,用“T”来代替具体的类型
public class SortHelper { public void BubbleSort(T[] arr) { int length = arr.Length; for (int i = 0; i < length-1; i++) { for (int j = 0; j < length-1-i; j++) { if (arr[j]>arr[j+1]) { T temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; } } } } }
这里我们需要把SortHelper定义类泛型类:
//定义泛型类SortHelper 这里“where T:IComparable” 是给类型参数T一个限制 -- 参数类型必须实现IComparable接口,否则无法通过编译 public class SortHelper<T> where T:IComparable { public void BubbleSort(T[] arr) { int length = arr.Length; for (int i = 0; i < length-1; i++) { for (int j = 0; j < length-1-i; j++) { if (arr[j].CompareTo(arr[j+1])>0) { T temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; } } } } }
测试一下:
static void Main(string[] args) { SortHelper<byte> sorter = new SortHelper<byte>(); byte[] a = { 4,5,1,3,2,8,5,0,2}; sorter.BubbleSort(a); SortHelper<int> sorter1 = new SortHelper<int>(); int[] b = { 4, 5, 1, 3, 2, 8, 5, 0, 2 }; sorter1.BubbleSort(b); //输出省略 }
输出:
0,1,2,2,3,4,5,5,8
0,1,2,2,3,4,5,5,8
3,为什么不用object
1)泛型不需要装箱和拆箱,性能好
2)泛型是类型安全的
3)泛型可以二进制代码重用
4,泛型约束:约束声明了泛型要求的类型参数的特征。
为了声明一个约束,需要使用where关键字,后跟一对”参数:要求”.其中,”参数”必须是泛型类型中定义的一个参数,而”要求”用于限制类型从
中”派生”的类或接口,或者限制必须存在一个默认构造器,或者限制使用一个引用/值类型约束.
约束的例子可以看这里:http://www.cnblogs.com/smiler/p/3163312.html
5,协变和逆变
示例代码从这里抄的:http://www.cnblogs.com/keiling/p/3672346.html