泛型

来源:互联网 发布:js模块化 剥离模块 编辑:程序博客网 时间:2024/05/16 19:56

概念

泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。

泛型的由来

现在需要我们来实现一个冒泡排序算法,那么不用泛型我们是怎么做呢?

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;                    }                }            }        }

现在我们把程序补充完整,运行看一下效果:

SortHelper sortHelper = new SortHelper();int[] array = { 1, 5, 9, 23, 6, 2 };sortHelper.BubbleSort(array);foreach (int i in array){     Console.Write("{0} ", i);}Console.ReadKey();

运行结果:
这里写图片描述

而现在呢,我们又有一个新的需求,需要对一个byte类型的数组进行排序,但是我们上面的排序算法只能接受Int类型的数组,那我们怎么办?
话说最简单的方法就是将上面的方法复制一遍,将类型改为byte。

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])                    {                        byte temp = array[j];                        array[j] = array[j - 1];                        array[j - 1] = temp;                    }                }            }        }

现在功能是实现了,但是这是我们想要的代码吗?如果我们还要对char类型等其他类型的数组进行排序呢?我们继续复制粘贴代码吗?那这样我们就需要思考一个更佳的解决方案了。
现在我们重新思考我们的实现过程,我们会发现这些方法的实现过程除了类型不同,代码几乎完全一样。

public void BubbleSort(int[] array)public void BubbleSort(byte[] array)

那我们该怎么办呢?
如果我们用一个类型参数T来代替int[]、byte[],其中类型参数T可以代表任何类型,那么这三个方法之间的差异是不是就被屏蔽掉了?

public void BubbleSort(T[] array)        {            int length = array.Length;            for (int i = 0; i < length - 2; i++) {                for (int j = length - 1; j > 1; j--) {                    T temp = array[j];                    array[j] = array[j - 1];                    array[j - 1] = temp;                }            }        }

但是问题又出现了,那么怎么知道T究竟是具体的哪个类型呢?
在.NET中,提供了专门的语法来传递T类型参数,其中一种就是定义类型的时候传递,此时,类型也就变成了泛型类。

public class SortHelper1<T>    {        public void BubbleSort(T[] array)        {            //方法的实现        }    }

在类名称的后面加了一个尖括号,使用这个尖括号来传递类型参数。下面我们看看究竟如何使用泛型。当我们需要对一个int类型的数组排序时:

//int类型SortHelper1<int> sortHelper = new SortHelper1<int>();int[] array = { 1, 5, 9, 23, 6, 2 };sortHelper1.BubbleSort(array);      foreach (int i in array)      {         Console.Write("{0} ", i);      }Console.ReadKey();

运行结果:
这里写图片描述

当我们需要为byte类型的数组进行排序时:

//byte类型SortHelper1<byte> sortHelper1 = new SortHelper1<byte>();byte[] array = { 1, 5, 9, 23, 6, 2 };sortHelper1.BubbleSort(array);foreach (int i in array){    Console.Write("{0} ", i);}Console.ReadKey();

运行结果:
这里写图片描述

现在我们可以看到,通过使用泛型,极大地减少了重复代码,是程序更加清爽。

类型参数约束

看到上面代码变的这么简洁,而且功能也实现了,终于可以休息一下了,可是娜娜又想到了这样一个问题:假设我们自己定义了一个类型(Book),这个类里面有两个字段:一个是int类型的Price,代表书的价格;一个是string类型的Title,代表书的标题

public class Book    {        private int price;        private string title;        public Book() { }        public Book(int price, string title) {            this.price = price;            this.title = title;        }        public int Price { get { return this.price; } }        public string Title { get { return this.title; } }        public int CompareTo(object obj) {            Book book2 = (Book)obj;            return this.Price.CompareTo(book2.Price);        }    }

现在,创建一个Book类型的数组,仿照上面的泛型类来进行排序

 SortHelper1<Book> sortHelper1 = new SortHelper1<Book>(); Book[] bookarray = new Book[2]; Book book1 = new Book(30, "安全信息资源管理"); Book book2 = new Book(20, "计算机网络"); bookarray[0] = book1; bookarray[1] = book2; sortHelper1.BubbleSort(bookarray); foreach (Book b in bookarray) {       Console.WriteLine("price:{0}", b.Price);       Console.WriteLine("titel:{0}", b.Title); }

实验的结果是这个程序并没有进行排序,所以我们应该具体告诉它我们按照哪个参数进行排序。

1 0