18-定义泛型方法
16.5 定义泛型方法
**本节视频教学录像:3分钟**
我们在编写程序时,经常遇到两个模块的功能非常相似,只是一个用于处理int数据,另一个用于处理string数据,或者其他自定义的数据类型,但我们没有办法,只能分别写多个方法处理每个数据类型,因为方法的参数类型不同。有没有一种办法,在方法中传入通用的数据类型,这样不就可以合并代码了吗?泛型方法就是专门解决这个问题的。
例如,我们熟悉的冒泡排序(Bubble Sort)算法实现将一个整数数组元素按照从小到大的顺序重新排列的功能。代码如下。
01 public class SortHelper //实现Bubble Sort算法的类SortHelper
02 {
03 public void BubbleSort(int [] array) {
04 int length = array.Length;
05 for (int i=0; i<= length -2;i++) {
06 for (int j= length -1; j>=1;j--)
07 if (array[j] < array[j - 1]) { //交换两个元素
08 int temp = array[j];
09 array[j] = array[j - 1];
10 array[j - 1] = temp
11 }
12 }
13 }
14 }
15 }
上述Bubble Sort算法只能接受一个int类型的数组,如果我们需要对一个byte类型的数组进行排序,只能将Bubble Sort算法代码复制一遍,并将方法的签名作相应改动。代码如下。
01 public class SortHelper //实现Bubble Sort算法的类SortHelper
02 {
03 public void BubbleSort(byte [] array) {
04 int length = array.Length;
05 for (int i=0; i<= length -2;i++) {
06 for (int j= length -1; j>=1;j--)
07 if (array[j] < array[j - 1])
{ //如果前面的元素较大,交换相邻两个元素
08 int temp = array[j];
09 array[j] = array[j - 1];
10 array[j - 1] = temp
11 }
12 }
13 }
14 }
然而,当我们下次需要对一个char类型的数组进行排序时,仍然需要将Bubble Sort算法代码复制一遍,并将方法的签名作相应改动。
仔细对比这两个方法,我们会发现除了方法的签名不同以外,这两个方法的实现完全一样。这时就可以将上面的方法体视为一个模板,将它的方法签名视为一个占位符,创建泛型方法来合并这两个方法的功能。
代码如下。
01 public class SortHelper //实现Bubble Sort算法的类SortHelper
02 {
03 public void BubbleSort <T>(T[] array) where T : IComparable {
04 int length = array.Length;
05 for (int i=0; i<= length -2;i++) {
06 for (int j= length -1; j>=1;j--)
07 if (array[j].CompareTo(array[j - 1]) < 0)
{ //如果前面的元素较大,交换相邻两个元素
08 int temp = array[j];
09 array[j] = array[j - 1];
10 array[j - 1] = temp
11 }
12 }
13 }
14 }
上述代码中,将方法签名中的参数类型int[]和byte[] 用占位符T[]来代替,并在类名称的后面加了一个尖括号,使用这个尖括号来传递占位符,也就是类型参数。其中“T”可以代表任何类型,这样就屏蔽了两个方法签名的差异。
**提示** 因为“<”和“>”运算符只对数值类型参数有效,要比较两个泛型类型参数值的大小,不能直接用“<”或“>”运算符。解决方法是约束泛型T为“where T : IComparable”,表明泛型T继承自IComparable 接口,可以使用IComparable 接口的CompareTo方法比较大小。
接着就可以像调用普通方法一样调用定义的泛型方法了,唯一的区别是在调用泛型方法时要实例化泛型T。代码如下。
01 class Program //实现Bubble Sort算法的类SortHelper
02 {
03 static void Main (string[] args) {
04 SortHelper sorter = new SortHelper();
05 int[] array = {8, 2, 4, 6, 10};
06 sorter.BubbleSort<int>(array);
07 foreach(int i in array) { //输出排序结果
08 Console.Write(“{0 }”,i);
09 }
10 Console.WriteLine();
11 Console.ReadKey();
12 }
13 }
将调用Bubble Sort算法把整型数组array的元素排序,并输出。其中语句:
sorter.BubbleSort<int>(array);
调用泛型方法BubbleSort
泛型方法的泛型参数,可以用在该方法的形参、方法体和返回值三处。上述例子中的泛型方法的泛型参数用在了方法的形参处。
**提示**
因为“<”和“>”运算符只对数值类型参数有效,要比较两个泛型类型参数值的大小,不能直接用“<”或“>”运算符。解决方法是约束泛型T为“where T : IComparable”,表明泛型T继承自IComparable 接口,可以使用IComparable 接口的CompareTo方法比较大小。