• 《C#高级编程》读书笔记(三):关于泛型


        一开始我觉着这本书太厚了,直到看到泛型这一章,发现这本书真不够,毕竟要把一个复杂的概念讲透,没一定的篇幅是不可能的。

        泛型这个概念困扰我很久了,所以我把这章翻来覆去看了好几遍,又去网上找了一些文章,算是搞明白了。

        先看看泛型的概念:“通过参数化类型来实现在同一份代码上操作多种数据类型。利用“参数化类型”将类型抽象化,从而实现灵活的复用”。所以,有了泛型,就可以创建独立于被包含类型的类和方法了。不必给不同的类型编写功能相同的许多方法或类,只创建一个方法或类即可。

        废话少说,来看代码:

        1,不用泛型的后果

        我们创建一个方法对int数组进行排序,算法是冒泡:    

        public class SortHelper
        {
            public void BubbleSort(int[] arr)
            {
                int length = arr.Length;
                for (int i = 0; i < length-1; i++)
                {
                    for (int j = 0; j < length-1-i; j++)
                    {
                        if (arr[j]>arr[j+1])
                        {
                            int temp=arr[j];
                            arr[j] = arr[j + 1];
                            arr[j + 1] = temp;
                        }
                    }
                }
            }
        }

      测试:

    static void Main(string[] args)
            {
                SortHelper sorter = new SortHelper();
                int[] a = { 4,5,1,3,2,8,5,0,2};
    
                sorter.BubbleSort(a);
    
           //输出省略
    }

      输出为:0,1,2,2,3,4,5,5,8

        如果数组是Byte类型的呢,简单,直接复制方法,改改签名就完事了

        public class SortHelper
        {
            public void BubbleSort(byte[] arr)
            {
                int length = arr.Length;
                for (int i = 0; i < length-1; i++)
                {
                    for (int j = 0; j < length-1-i; j++)
                    {
                        if (arr[j]>arr[j+1])
                        {
                            byte temp = arr[j];
                            arr[j] = arr[j + 1];
                            arr[j + 1] = temp;
                        }
                    }
                }
            }
        }

      如果再引入其他数据类型的方法呢,那这个类就没法看了,长不说,维护起来也很麻烦,如果我想把冒泡改为快排,那每个方法都要改,那怎么办呢,这个时候就可以引入泛型。

        2,使用泛型

        简而言之,用“T”来代替具体的类型

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

      这里我们需要把SortHelper定义类泛型类:

        //定义泛型类SortHelper 这里“where T:IComparable” 是给类型参数T一个限制 -- 参数类型必须实现IComparable接口,否则无法通过编译
        public class SortHelper<T> where T:IComparable
        {
            public void BubbleSort(T[] arr)
            {
                int length = arr.Length;
                for (int i = 0; i < length-1; i++)
                {
                    for (int j = 0; j < length-1-i; j++)
                    {
                        if (arr[j].CompareTo(arr[j+1])>0)
                        {
                            T temp = arr[j];
                            arr[j] = arr[j + 1];
                            arr[j + 1] = temp;
                        }
                    }
                }
            }
        }

      测试一下:

            static void Main(string[] args)
            {
                SortHelper<byte> sorter = new SortHelper<byte>();
                byte[] a = { 4,5,1,3,2,8,5,0,2};
    
                sorter.BubbleSort(a);
    
                SortHelper<int> sorter1 = new SortHelper<int>();
                int[] b = { 4, 5, 1, 3, 2, 8, 5, 0, 2 };
    
                sorter1.BubbleSort(b);
           //输出省略
            }

    输出:  

    0,1,2,2,3,4,5,5,8

    0,1,2,2,3,4,5,5,8

        3,为什么不用object

             1)泛型不需要装箱和拆箱,性能好

             2)泛型是类型安全的

             3)泛型可以二进制代码重用

        4,泛型约束:约束声明了泛型要求的类型参数的特征。

        为了声明一个约束,需要使用where关键字,后跟一对”参数:要求”.其中,”参数”必须是泛型类型中定义的一个参数,而”要求”用于限制类型从

    中”派生”的类或接口,或者限制必须存在一个默认构造器,或者限制使用一个引用/值类型约束.

           约束的例子可以看这里:http://www.cnblogs.com/smiler/p/3163312.html

        5,协变和逆变

    示例代码从这里抄的:http://www.cnblogs.com/keiling/p/3672346.html

  • 相关阅读:
    Introduction to Oracle9i: SQL left join 和 left outer join 的区别
    ORACLE10G RMAN 命令
    Oracle管理与维护.手工创建数据库以及脚本
    RMAN 备份基本用法
    ASM 常用概念解释
    oracle学习笔记之二:数据类型之DATETIME 收藏
    10g中表监控与statistics_level
    Oracle 学习笔记: RMAN常用命令
    Oracle 进程类别
    ORACLE TRUNC()函数
  • 原文地址:https://www.cnblogs.com/khjian/p/5615935.html
Copyright © 2020-2023  润新知