C#學習-- 泛型Generic

這篇博客就C#的特性--泛型(Generic)做一下簡單介紹:


學過C++的朋友應該都知道C++模板(Template)這一特性,C#中的泛型相當於C++中的模板


(一).在介紹泛型之前,我們先考慮以下情況:

假設我們現在需要寫一個比較類,這個類需要對傳入的兩個double類型的數據進行比較大小操作,實現代碼如下:

public class DoubleCompare
{
    private double x,y;

    public void Compare(double a,double b)//賦值函數
    {
        x=a;
        y=b;
    }

    public double Max()//返回較大值
    {    
        return (x>y)?x:y;
    }

    public double Min()//返回較小值
    {
        return (x<y)?x:y;
    }
}


Main函數調用如下:

static void Main(string[] args)
{
    DoubleCompare compare = double DoubleCompare();

    double a = 3;
    double b = 4;

    compare.Compare(a,b);

    double max = compare.Max();
    double min = compare.Min();
         
    Console.Write("Max:" + max + "  Min:" + min);
    Console.ReadKey();
}

運行結果如下:

 

 

這時,假如我們還需要一個相似的比較類,功能與DoubleCompare類相同,只是要處理的是兩個String類型的字符,這時我們需要再寫一個StringCompare類,代碼如下:

public class StringCompare
{
    private string x,y;

    public void Compare(string a,string b)//賦值函數
    {
        x=a;
        y=b;
    }

    public string Max()//返回較大值
    {    
        return (string.Compare(x,y) > 0) ? x : y;
    }

    public string Min()//返回較小值
    {
        return (string.Compare(x,y) < 0) ? x : y;
    }
}
我們可以看到,兩個類的功能完全一致只是處理數據的類型不一樣。但沒有辦法,因爲類中方法的參數類型不同只能寫多個分別處理每個數據類型,這就造成了代碼的冗餘和不必要的開銷

 

(二).

有沒有一種辦法,在方法中傳入通用的數據類型,實現一類多用,這樣不就可以合併代碼了嗎?泛型的出現就是專門解決這個問題的。

我們先用泛型寫出一個通用類:

public class GenericCompare<T> where T : IComparable
    {
        private T x,y;

        public void Compare(T a,T b)//複製函數
        {
            x=a;
            y=b;
        }

        public T Max()//返回較大值
        {    
            return (x.CompareTo(y) > 0) ? x : y;
        }

        public T Min()//返回較小值
        {
            return (x.CompareTo(y) < 0) ? x : y;
        }
 }

注意這句代碼:

public class GenericCompare<T> where T : IComparable
我們注意到,泛型類在聲明時類名後多了一對尖括號<>,裏面的類型T就是通用類型,在初始化類對象時T可以是Double、String或者其他類型。

因爲要對元素進行比較,所以泛型要約束成實現IComparable接口:

where T : IComparable

接下來,我們再修改Main函數,

static void Main(string[] args)
{
    //實例化泛型的類對象時也需要用<>表示對象的類型
    GenericCompare<double> double_compare = new GenericCompare<double>();
    GenericCompare<string> string_compare = new GenericCompare<string>();

    double a = 3;
    double b = 4;
    string c = "C";
    string d = "D";

    double_compare.Compare(a, b);
    string_compare.Compare(c, d);

    double max1 = double_compare.Max();
    double min1 = double_compare.Min();
    string max2 = string_compare.Max();
    string min2 = string_compare.Min();

    Console.Write("Max1:" + max1 + "  Min1:" + min1 + "\n");
    Console.Write("Max2:" + max2 + "  Min2:" + min2 + "\n");
    Console.ReadKey();

}

運行結果如下:

 

我們可以看到,在實例化泛型的類對象時也需要用<>表示對象的類型

C#泛型類在編譯時,先生成中間代碼,通用類型T只是一個佔位符。在實例化類時,根據用戶指定的數據類型代替T並由即時編譯器生成本地代碼,這個本地代碼中已經使用了實際的數據類型,等同於用實際類型寫的類,所以不同的封閉類的本地代碼是不一樣的。按照這個原理,我們可以這樣認爲:

泛型類的不同的封閉類是分別不同的數據類型

例如GenericCompare<double>和GenericCompare<string>是兩個完全沒有任何關係的類,你可以把他看成類A和類B。

 


以上。

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章