1. 程式人生 > >深入理解C#中的泛型(二)

深入理解C#中的泛型(二)

  接著深入理解C#中的泛型(一),這篇文章主要講解泛型類、泛型方法、泛型與集合。

泛型類

  如果我們想對一個類的所有泛型方法進行統一引數約束,我們把約束條件加在類上,此時這個類便成為泛型類,如下:
 public class SortHelper<T> where T : IComparable

泛型方法

  如果一個類中只有某個方法使用了泛型,這時我們自然會想到:有沒有辦法把引數T加到方法上,而非整個類上,也就是降低T作用的範圍。答案是可以的,我們稱這樣的方法為泛型方法,如下:
 public class SortHelper
    {
        //引數為T的氣泡排序
        public void BubbleSort<T>(T[] array) where T : IComparable
        {
            int length = array.Length;

            for (int i = 0; i <= length - 2; i++)
            {
                for (int j = length - 1; j >= 1; j--)
                {
                    //對兩個元素進行交換
                    if (array[j].CompareTo(array[j - 1]) < 0)
                    {
                        T temp = array[j];
                        array[j] = array[j - 1];
                        array[j - 1] = temp;
                    }
                }
            }
        }
    }

  儘管BubbleSort()是一個泛型方法,但在使用上與普通方法沒有任何區別。

泛型與集合

  說起泛型,我們就不得不提到集合型別,因為使用泛型能夠極大地提高集合型別的效能和安全性。

   避免隱式的裝箱和拆箱

ArrayList list = new ArrayList();
            const int ListSize = 3;

            for (int i = 0; i < ListSize; i++)
            {
                list.Add(i);
            }

            for (int i = 0; i < ListSize; i++)
            {
                int value = (int)list[i];
                Console.WriteLine(value);
            }
         上述程式碼是“可以執行的程式碼”,而非“好的”程式碼。因為ArrayList型別為了包含任何型別,所有它接受的引數為所有型別的基類Object,Object是一個引用型別,而int是一個值型別,因此當呼叫list.Add(i)時,存在一個裝箱的操作。同理,當從ArrayList中獲取元素時,又需要進行一個拆箱的操作:int value=(int)list[i]。這兩個操作是相對耗時的,尤其是當集合型別包含的元素比較多或值型別比較大的時候。   通過使用泛型,由於集合中的元素型別在編譯時已經確定,就避免了裝箱和拆箱的操作,這樣顯著提高了集合型別的效能。
            List<int> list = new List<int>();
            const int ListSize = 3;

            for (int i = 0; i < ListSize; i++)
            {
                list.Add(i);
            }

            for (int i = 0; i < ListSize; i++)
            {
                int value = (int)list[i];
                Console.WriteLine(value);
            }

   編譯時的型別安全

            ArrayList list = new ArrayList();
            int i = 100;
            list.Add(i);
            string value = (string)list[0];
     大家一看就能發現這段程式碼有問題,因為型別不匹配。可惜的是,編譯器無法知道,因為對它來說,不管是int還是string,它們都是Object型別。對於上面的問題,編譯器無能為力,因為它認為其是合法的,編譯可以順利通過,只有在執行時才會跑出異常。   通過使用泛型集合,這種情況將不復存在,當試圖進行類似上面的轉換時,根本無法通過編譯:
            List<int> list = new List<int>();
            int i = 100;
            list.Add(i);
            string value = (string)list[0]; //編譯錯誤
        到此,關於C#中泛型的理解講解完畢,希望可以幫助大家進步。