类型参数使得设计类和方法时,不必确定一个或多个具体参数,其的具体参数可延迟到客户代码中声明、实现。
这意味着使用泛型的类型参数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 ISports21 {22 void KickShuttlecock();23 }24 25 public interface IWork26 {27 void DoJob();28 }29 30 public class Chinese : People, ISports, IWork31 {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);
原标题:using System.Collections.Generic;
关键词: