首页 > 学院 > 开发设计 > 正文

(转)C#中的泛型

2019-11-15 02:27:59
字体:
来源:转载
供稿:网友

(转)C#中的泛型

来源:http://www.VEVb.com/JimmyZhang/archive/2008/12/17/1356727.html

.Net 1.1版本最受诟病的一个缺陷就是没有提供对泛型的支持。通过使用泛型,我们可以极大地提高代码的重用度,同时还可以获得强类型的支持,避免了隐式的装箱、拆箱,在一定程度上提升了应用程序的性能。本文将系统地为大家讨论泛型,我们先从理解泛型开始。

1.1 理解泛型

1.1.1 为什么要有泛型?

我想不论大家通过什么方式进入了计算机程序设计这个行业,都免不了要面对数据结构和算法这个话题。因为它是计算机科学的一门基础学科,往往越是底层的部分,对于数据结构或者算法的时间效率和空间效率的要求就越高。比如说,当你在一个集合类型(例如ArrayList)的实例上调用Sort()方法对它进行排序时,.Net框架在底层就应用了快速排序算法。.Net框架中快速排序方法名称叫QuickSort(),它位于Array类型中,这可以通过Reflector.exe工具查看到。

我们现在并不是要讨论这个QuickSort()实现的好不好,效率高还是不高,这偏离了我们的主题。但是我想请大家思考一个问题:如果由你来实现一个排序算法,你会怎么做?好吧,我们把题目限定得再窄一些,我们来实现一个最简单的冒泡排序(Bubble Sort)算法,如果你没有使用泛型的经验,我猜测你可能会毫不犹豫地写出下面的代码来,因为这是大学教程的标准实现:

public class SortHelper{ public void BubbleSort(int[] array) { int length = array.Length; for (int i = 0; i <= length - 2; i++) { for (int j = length - 1; j >= 1; j--) { // 对两个元素进行交换 if (array[j] < array[j - 1] ) { int temp = array[j]; array[j] = array[j - 1]; array[j - 1] = temp; } } } }}

对冒泡排序不熟悉的读者,可以放心地忽略上面代码的方法体,它不会对你理解泛型造成丝毫的障碍,你只要知道它所实现的功能就可以了:将一个数组的元素按照从小到大的顺序重新排列。我们对这个程序进行一个小小的测试:

class PRogram { static void Main(string[] args) { SortHelper sorter = new SortHelper(); int[] array = { 8, 1, 4, 7, 3 }; sorter.BubbleSort(array); foreach(int i in array){ Console.Write("{0} ", i); } Console.WriteLine(); Console.ReadKey(); }}

输出为:

1 3 4 7 8

我们发现它工作良好,欣喜地认为这便是最好的解决方案了。直到不久之后,我们需要对一个byte类型的数组进行排序,而我们上面的排序算法只能接受一个int类型的数组,尽管我们知道它们是完全兼容的,因为byte类型是int类型的一个子集,但C#是一个强类型的语言,我们无法在一个接受int数组类型的地方传入一个byte数组。好吧,没有关系,现在看来唯一的办法就是将代码复制一遍,然后将方法的签名改一个改了:

public class SortHelper { public void BubbleSort(int[] array) { int length = array.Length; for (int i = 0; i <= length - 2; i++) { for (int j = length - 1; j >= 1; j--) { // 对两个元素进行交换 if (array[j] < array[j - 1]) { int temp = array[j]; array[j] = array[j - 1]; array[j - 1] = temp; } } } } public void BubbleSort(byte[] array) { int length = array.Length; for (int i = 0; i <= length - 2; i++) { for (int j = length - 1; j >= 1; j--) { // 对两个元素进行交换 if (array[j] < array[j - 1]) { int temp = array[j]; array[j] = array[j - 1]; array[j - 1] = temp; } } } }}

OK,我们再一次解决了问题,尽管总觉得哪里有点别扭,但是这段代码已经能够工作,按照敏捷软件开发的思想,不要过早地进行抽象和应对变化,当变化第一次出现时,使用最快的方法解决它,当变化第二次出现时,再进行更好的构架和设计。这样做的目的是为了避免过度设计,因为很有可能第二次变化永远也不会出现,而你却花费了大量的时间精力制造了一个永远也用不到的“完美设计”。这很像一个谚语,“fool me once,shame on you. fool me twice, shame on me.”,翻译过来的意思是“愚弄我一次,是你坏;愚弄我两次,是我蠢”。

美好的事情总是很难长久,我们很快需要对一个char类型的数组进行排序,我们当然可以仿照byte类型数组的作法,继续采用复制粘贴大法,然后修改一下方法的签名。但是很遗憾,我们不想让它愚弄我们两次,因为谁也不想证明自己很蠢,所以现在是时候思考一个更佳的解决方案了。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表