【转载】C#中的泛型

时间:2021-10-25 08:36:34

标签:

1.1 C#中的泛型

.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 - 1; i++) { for (int j = length - 1; j >i; 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 - 1; i++) { for (int j = length - 1; j >i; 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 - 1; i++) { for (int j = length - 1; j >i; 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类型数组的作法,继续给与复制粘贴大法,然后改削一下要领的签名。但是很遗憾,我们不想让它愚弄我们两次,因为谁也不想证明本身很蠢,所以此刻是时候思考一个更佳的解决方案了。

我们仔细地比拟这两个要领,会发明这两个要领的实现完全一样,除了要领的签名差别以外,没有任何的区别。如果你曾经开发过Web站点措施,会知道对付一些浏览量非常大的站点,为了制止处事器承担过重,凡是会给与静态页面生成的方法,因为使用Url重写仍要要耗费大量的处事器资源,但是生成为html静态网页后,处事器仅仅是返回客户端请求的文件,能够极大的减轻处事器承担。