C#泛型

在编写程序时,常常遇到两个模块的功能非常相似,例如:
 class Class01
    {

        public void BubbleSort(int[] array)
        {
            int length = array.Length;

            for (int i = 0; i < length ; 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;
                    }
                }
                Console.WriteLine(array[i]);

            }
        }

class Program
    {
        
        static void Main(string[] args)
        {
            Class01 cl1 = new Class01();
            int[] arr = { 9,1,3,7,6,4};
            cl1.BubbleSort(arr);  
            Console.ReadKey();
        }
    }
像这样简单的冒泡排序就完成了,当我们要对byte类型数组进行排序的时候,只需要将上面代码复制一下把int改成byte就可以了,这样写虽然程序能够很好的执行,但如果以后我还要增加相同功能类型不同的时候,在复制在更改吗,显然这样变得很繁琐,而且最重要的一个原因是在处理值类型的时候,需要将值类型转换为引用类型,进行装箱,而当装箱的值类型要转换为值类型时又要进行拆箱操作(在拆箱的时候需要使用类型强制转换符),明显性能损失很大。
那么这时候泛型就出现了,有了泛型,就可以创建独立于被包含类型的类和方法了,我们不必给不同的类型编写相同的许多方法和类,只创建一个方法或类即可。泛型类使用泛型类型,并可以根据需要用特定的类型替换泛型类型,这就保证了类型的安全性,如果某个类型不支持泛型类,编译器就会出现错误。例如:
var list = new List<int>();
list.Add(30);
list.Add("Coyote"); //编译报错,因为list已经指定了Int类型
list.Add(new Class1()); //编译报错,因为list已经指定了Int类型

1.泛型的命名约定:
 ·泛型类型的名称用字母T作为前缀。
 ·如果没有特殊的要求,泛型类型允许用任意类型替代,如只使用一个泛型类型,就可以用字符T作为泛型类型的名称。
public void List<T>(){}
·在创建泛型类时,还需要一些其他C#关键字,例如不能把null赋予泛型类型,可以使用default,原因是null只能用于引用类型,而通过default关键字,可以将null赋予引用类型,将0赋予值类型。如果泛型类型不需要Object类的功能,但需要调用泛型类上的某些特定方法,就可以定义约束
了解了泛型类型后,我们为上面的冒泡排序来用泛型实现:
 //泛型约束,T类型必须实现接口IComparable
    class Class01<T> where T:IComparable
    {
        
        public void BubbleSort(T[] array)
        {
            int length = array.Length;

            for (int i = 0; i < length ; i++)
            {
                for (int j = length - 1; j >= 1; j--)
                {
                    //元素进行比较,array[j]比array[j-1]小,返回一个小于0的整数,相等返回0,大于返回一个大于0的整数
                    if (array[j].CompareTo( array[j - 1]) < 0)
                    {
                        T temp = array[j];
                        array[j] = array[j - 1];
                        array[j - 1] = temp;
                    }
                }
                Console.WriteLine(array[i]);

            }

 class Program
    {
        
        static void Main(string[] args)
        {
            Class01<int> cl1 = new Class01<int>();
            int[] arr = { 9,1,3,7,6,4};
            cl1.BubbleSort(arr);
            byte[] by = { 9, 1, 3, 7, 6, 4 };
            Class01<byte> cl2 = new Class01<byte>();
            cl2.BubbleSort(by);
           
            Console.ReadKey();
        }

除了约束类型参数T实现某个接口以外,还可以约束T是一个结构,是一个类,是一个默认构造函数等。但注意,只能为默认构造函数定义构造函数约束,不能为其他构造函数定义构造函数约束


参考文献:http://www.cnblogs.com/JimmyZhang/archive/2008/12/17/1356727.html     《C#高级编程第八版》

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值