首页 > 代码库 > C#中的泛型-1

C#中的泛型-1

    在软件这个行业,做的越久,往往会觉得很多技术问题最终会偏向数据结构和算法。

    记得曾经大学的一堂课上,老师讲了一个关于冒泡排序的算法,下面是课本上的标准实现。

 1 public class Sort
 2      {
 3          public void sortArray(int[] arry)
 4          {
 5              int length = arry.Length;
 6              for (int i = 0; i <= length - 2; i++)
 7              {
 8                  for (int j = length - 1; j >= 1; j--)
 9                  {
10                      if (arry[j]<arry[j - 1])
11                      {
12                          int temp = arry[j];
13                          arry[j] = arry[j - 1];
14                          arry[j - 1] = temp;
15                      }
16                  }
17              }
18          }
19      }

    当然,就排序本身不是我们这里要讨论的问题。上面的代码实现了一个功能:将一组数组元素按照从大到小的顺序排列。
    进行简单的测试

 1 static void Main(string[] args)
 2         {
 3             Sort sor = new Sort();
 4             //创建一个int数组
 5             int[] array = { 8,1,4,7,3};
 6             //排序
 7             sor.sortArray(array);
 8             //打印排序结果
 9             foreach (int i in array)
10             {
11                 Console.WriteLine("{0} : ",i);
12             }
13             Console.ReadLine();
14         }

得到的结果是:
1  3  4  7  8

    发现结果ok,心想这就是完美的了。但是不久之后,又需要对一个byte数组进行排序,而这个程序只接受int型参数,尽管byte的数据范围是int的子集,但是强类型的C#语言不允许我们在一个接受int的地方传入byte,不过没关系,灵机一动,把上面代码复制一边,参数改为byte[]不久好了。

 

 1 public class Sort
 2      {
 3          public void sortArray(byte[] arry)
 4          {
 5              int length = arry.Length;
 6              for (int i = 0; i <= length - 2; i++)
 7              {
 8                  for (int j = length - 1; j >= 1; j--)
 9                  {
10                      if (arry[j] < arry[j - 1])
11                      {
12                          byte temp = arry[j];
13                          arry[j] = arry[j - 1];
14                          arry[j - 1] = temp;
15                      }
16                  }
17              }
18          }
19      }

    以往写代码首先是要实现功能,功能实现了,下一步才是讨论如何优化。因为设计之处,大家能够想到很多很多可能面临的问题,但实际上有些问题可能永远不会发生,你却花费了大量的时间。我啰嗦这句话的意思其实是想告诉大家,不要过早的进行抽象化和应对变化。上面两个方法已经很好的解决了int和byte的问题,但是新的需求又来了,这一次需要对char类型的数组进行排序。当然可以继续copy上面的方法,可是似乎聪明的人不能接受,我们要善于总结归纳,这是曾经上学时我认为学习数学和物理最重要的方法。
    对比前面两个方法,它们除了方法的签名不同之外完全是一样的,曾经开发web的时候,在web上生成静态页面最常用的一个方式是使用模版,每次生成静态页面的时候先加载模版,模版中含有特殊的占位符,然后从数据库读取数据,使用取出的数据替换这些占位符,最后将模版按照一定的命名规范生成HTML静态文件保存在服务器上,所以服务器无需重写url,只需要把静态文件返回给客户端就好了。

    基于这种思路,我们上面的方法可以视为一个模版,而int[],byte[]的位置就使用占位符来替换掉好了。

    于是,把int,byte,char等等都看作是->T,T代表所有类型。

    这个时候方法的签名就是下面这样了:

 public void sort(T[] arry)
 

    但是又有问题了,T怎么知道自己是谁呢?int,byte还是其他?有人可能想到,通过类的构造方法传递T的类型,这里要说明的是,构造方法接受的参数是类型的实例,而T本身就是类型,显然无法传递它。

public Sort(类型的实例);

    .NET专门定义了一种类型传递方式

1 public class SortHelper<T>      {
2          public void sort(T[] arry)
3          {
4              ......
5           }
6      }

    使用方法:

1 Sort<byte> sort  = new Sort<byte>();
2 byte[] array = {8,1,4,7,3};
3 sort.sortArray(array);

    此时,T知道自己是byte了,但是编译后发现错误,这是下一次要讨论的问题~