類型參數使得設計類和方法時,不必確定一個或多個具體參數,其的具體參數可延遲到客戶代碼中聲明、實現。 這意味著使用泛型的類型參數T,寫一個類MyList<T>,客戶代碼可以這樣調用:MyList<int>, MyList<string>或 MyList<MyClass>。 這避免了運行時類型轉換或裝箱 ...
類型參數使得設計類和方法時,不必確定一個或多個具體參數,其的具體參數可延遲到客戶代碼中聲明、實現。
這意味著使用泛型的類型參數T,寫一個類MyList<T>,客戶代碼可以這樣調用:MyList<int>, MyList<string>或 MyList<MyClass>。
這避免了運行時類型轉換或裝箱操作的代價和風險。
下麵是普通的方法調用:
1 public static void ShowInt(int iValue) 2 { 5 Console.WriteLine(" ShowInt方法 展示{0},其類型為{1}", iValue, typeof(int));//,iValue.GetType()); 6 } 7 8 public static void ShowLong(long lValue) 9 { 10 Console.WriteLine(" ShowLong方法 展示{0},其類型為{1}", lValue, lValue.GetType()); 11 } 12 13 public static void ShowString(string sValue) 14 { 15 Console.WriteLine(" ShowString方法 展示{0},其類型為{1}", sValue, sValue.GetType()); 16 } 17 18 public static void ShowDateTime(DateTime dValue) 19 { 20 Console.WriteLine(" ShowDateTime方法 展示{0},其類型為{1}", dValue, dValue.GetType()); 21 }
這樣,每次都需要根據不同的類別調用不同的方法,這是很不方便的。
/// <summary> /// 1 通過繼承,子類擁有父類的一切屬性和行為,任何父類出現的地方,子類都可以代替 /// 2 object 類型是一切類型的父類 /// </summary> /// <param name="oValue"></param> public static void ShowObject(object oValue) { Console.WriteLine(" ShowObject方法 展示{0},其類型為{1}", oValue, oValue.GetType()); }
這樣,通過萬類之母object,不論什麼類型都可以調用,只需要一個方法,達到了代碼的重用。
但是,需要裝箱和拆箱操作,有效率上的損失,所以請看下麵的方法:
1 public static void Show<T>(T tValue) 2 { 3 Console.WriteLine(" Show<T>方法 展示{0},其類型為{1}", tValue, tValue.GetType());4 }
通過泛型的延遲申明,可以將兩者的不足之處相互結合,達到代碼的重用。
所謂延遲申明,就是先不什麼類型,用一個占位符代替,當要使用的時候再指定所需要的類型。
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------泛型約束:
class代表引用類型,struct代表值類型。
1 public static T Show<T>(T tValue) 2 //where T : class //引用類型 3 //where T : struct //值類型 4 { 5 Console.WriteLine(" Show<T>方法 展示{0},其類型為{1}", tValue, tValue.GetType());//,iValue.GetType());// 6 return default(T);//根據泛型類型,提供預設值 7 }
1 public class BaseModel 2 { 3 public int Id { get; set; } 4 public string TableName { get; set; } 5 } 6 7 public class People : BaseModel 8 { 9 public People() 10 { } 11 public string Name { get; set; } 12 public int Age { get; set; } 13 public string Sex { get; set; } 14 /// <summary> 15 /// 打招呼 16 /// </summary> 17 public string Hi { get; set; } 18 } 19 20 public interface ISports 21 { 22 void KickShuttlecock(); 23 } 24 25 public interface IWork 26 { 27 void DoJob(); 28 } 29 30 public class Chinese : People, ISports, IWork 31 { 32 public string Majiang { get; set; } 33 /// <summary> 34 /// 構造函數 35 /// </summary> 36 /// <param name="name"></param> 37 public Chinese(string name) 38 { 39 base.Hi = "早上好,吃了嗎"; 40 base.TableName = "P_Chinese"; 41 } 42 public Chinese() 43 { 44 base.Hi = "早上好,吃了嗎"; 45 base.TableName = "P_Chinese"; 46 } 47 48 49 public void KickShuttlecock() 50 { 51 Console.WriteLine("踢毽子"); 52 } 53 54 public void DoJob() 55 { 56 Console.WriteLine("養家糊口"); 57 } 58 }View Code
1 public static T Hi<T>(T t) where T : People, ISports, IWork, new() 2 { 3 T tModel = new T();//new()約束表明T擁有一個無參數的構造函數 4 tModel.Id = 11;//People約束決定 5 tModel.Name = "花心胡蘿蔔";//people約束決定 6 tModel.Sex = "男";//people約束決定 7 8 tModel.KickShuttlecock();//ISports介面約束決定 9 tModel.DoJob();//IWork介面約束決定 10 return tModel; 11 }
通過上面看出來,約束就是一種限定。只有符合約束類型的參數才能代替給定的類型參數。
比如下麵的調用:
1 Chinese chinese = new Chinese() 2 { 3 Id = 123, 4 Name = "天忝♂開心" 5 }; 6 GenericConstraint.Hi<Chinese>(chinese);