這篇博客就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。
以上。