1. 程式人生 > >面向對象設計——“泛型”的起步

面向對象設計——“泛型”的起步

rac -m sharp mil rabl dex 兩個 無法 ini

泛型是 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;
                }
            }
        }
    }

這是泛型的一個最典型的應用。能夠看到,通過使用泛型。我們極大地降低了反復代碼,使我們的程序更加清爽,泛型類就類似於一個模板,能夠在須要時為這個模板傳入不論什麽我們須要的類型。

面向對象設計——“泛型”的起步