首页 > 代码库 > 面向对象设计——“泛型”的起步

面向对象设计——“泛型”的起步

        泛型是 2.0 版 C# 语言和公共语言执行库 (CLR) 中的一个新功能。泛型将类型參数的概念引入 .NET Framework,类型參数使得设计例如以下类和方法成为可能:这些类和方法将一个或多个类型的指定推迟到client代码声明并实例化该类或方法的时候。比如,通过使用泛型类型參数 T,您可以编写其它client代码可以使用的单个类,而不致引入执行时强制转换或装箱操作的成本或风险。

——MSDN


        我的计算机是以Visual Basic 6.0拉开帷幕的。让我印象比較深的是两个排序:选择排序和冒泡排序。当然本文不是来讨论这两个排序的详细实现。更不讨论差别。那要干吗呢?请往下看。


        对于选择排序。完毕从小到大的排序。我们要怎么实现功能呢?对于当时的我,肯定毫不犹豫的写出以下的代码。由于课本中就是这种实现思路:

    public class SelectionSort
    {
        public void Sort(int[] array)
        {
            int length = array.Length;

            for (int i = 0; i < length - 1; i++)
            {
                for (int j = i + 1; j < length; j++)
                {
                    // 对两个元素进行交换
                    if (array[i] > array[j])
                    {
                        int temp = array[i];
                        array[i] = array[j];
                        array[j] = temp;
                    }
                }
            }
        }
    }
        我们来測试一下:
        static void Main(string[] args)
        {
            SelectionSort sorter = new SelectionSort();
            int[] array = { 5, 2, 0, 1, 3, 1, 4 };
            sorter.Sort(array);
            foreach (int i in array) Console.Write(i + " ");
            Console.WriteLine();
            Console.Read();
        }
        输出结果:0 1 1 2 3 4 5
        非常不错,比較easy实现了功能。

再看看上面的代码,我们实现的是对int类型数据的排序,假设我们换成byte该怎么弄呢?对于VB6.0中。他们是全然兼容的。由于VB6.0可以自己主动进行隐式转换,但C#是一个强类型的语言,无法在一个接受int数组类型的地方传入一个byte数组。

事实上也不难。我们仅仅须要复制一下代码,然后改一下參数类型就OK了:

    public class SelectionSort
    {
        public void Sort(byte[] array)
        {
            int length = array.Length;

            for (int i = 0; i < length - 1; i++)
            {
                for (int j = i + 1; j < length; j++)
                {
                    // 对两个元素进行交换
                    if (array[i] > array[j])
                    {
                        byte temp = array[i];
                        array[i] = array[j];
                        array[j] = temp;
                    }
                }
            }
        }
    }
        不能高兴的太早,如今又有新需求了,须要对一个char类型的数据进行排序,当然我们能够继续依照上面的思路,採用复制粘贴,然后改一下数据类型。这里就不写代码了!


        我们细致地对照这几个实现方法,会发现方法的实现全然一样,除了方法的签名不同以外,没有不论什么的差别。但是完毕这三个功能,代码的反复度、代码的冗余相当大。对于编程这但是不好味道。

那么有没有一种机制,或者说有这样一个keyword。来取代不论什么类型呢?我们如果有这样一个关系字叫“T”:

    public class SelectionSort
    {
        public void Sort(T[] array)
        {
            int length = array.Length;

            for (int i = 0; i < length - 1; i++)
            {
                for (int j = i + 1; j < length; j++)
                {
                    // 对两个元素进行交换
                    if (array[i] < array[j])
                    {
                        T temp = array[i];
                        array[i] = array[j];
                        array[j] = temp;
                    }
                }
            }
        }
    }
        啊。这效果看起来怎一个“爽”字了得。当然上面的代码是错误的,C#会报错的。到如今,也用不着卖乖了。C#已经帮我们实现了这样的效果。那就是泛型。

在.Net中。实现比較的基本方法是实现IComparable接口:

    public class SelectionSort
    {
        public void Sort<T>(T[] array) where T : IComparable
        {
            int length = array.Length;
            for (int i = 0; i < length - 1; i++)
            {
                T min = array[i];
                int minIndex = i;
                for (int j = i + 1; j < length; j++)
                {
                    if (min.CompareTo(array[j]) > 0)
                    {
                        min = array[j];
                        minIndex = j;
                    }
                }
                if (minIndex != i)
                {
                    array[minIndex] = array[i];
                    array[i] = min;
                }
            }
        }
    }

        这是泛型的一个最典型的应用。能够看到,通过使用泛型。我们极大地降低了反复代码,使我们的程序更加清爽,泛型类就类似于一个模板,能够在须要时为这个模板传入不论什么我们须要的类型。

面向对象设计——“泛型”的起步