延迟声明:声明方法的时候并没有指定参数类型,而是等到调用的时候指定
如何声明和使用泛型
普通类不能直接继承泛型类
指定类型参数后才可以
普通类不能直接实现泛型接口
泛型类可以直接继承泛型类
泛型的好处和原理
声明方法的时候并没有指定参数类型,而是等到调用的时候指定
编译的时候 类型参数编译为占位符
程序运行的时候,jit即时编译替换为真实类型
值类型参数,会装箱拆箱
object是一切类型的父类
通过继承,子类拥有父类的一切属性和行为;任何父类出现的地方,都可以用子类来代替
泛型类、泛型方法、泛型接口、泛型委托
泛型约束
有约束才有自由 有权利就得有义务
基类约束,就可以访问基类的属性和方法
必须是基类/子类
协变 逆变(选修)
只能放在接口或者委托的泛型参数前面
out 协变covariant 修饰返回值
in 逆变contravariant 修饰传入参数
泛型缓存(选修)
字典缓存:静态属性常驻内存
泛型类
1 public class people<T> 2 { 3 public T get(T t) { 4 return t; 5 } 6 } 7 8 9 int temp= p.get(10);
有相同的逻辑,但是类型不同 延时声明类型
泛型方法
public void Show<T>(){} public void Show<T>(T tParameter){}
泛型类
public class Generic<T,T1,T2>{ public void Show(T t){} }
泛型接口
public interface IPeople<T>{T Work();}
泛型委托
public delegate T GetNum<T>();
泛型继承(普通类不能直接继承泛型类、泛型接口)
1可以指定类型后
泛型约束 基类约束
public void Show<T>(T tParameter) where T:People
{
}
接口约束
public void ShowInterface<T>(T tParameter) where T:ISports
引用类型约束
public static T Get<T>() where T:class //where T : class//引用类型约束
{
return null;
}
值类型约束
public static T Get<T>() where T:struct //where T : struct//值类型约束
{
return default(T);
}
无参数构造函数约束 可以new T 没有有参数构造函数约束
public static T Get<T>() where T:new() //无参数构造函数约束
{
T t=new T();
}
协变 逆变 只能出现在接口或委托 net 3.0
Out 协变 减少写代码
public interface IStudent<out T>//out 即协变 只能为返回值 { T Get(); T Get1(T t); //不能作为传入参数 此句报错 }
/// <summary> /// 逆变 /// </summary> /// <typeparam name="T"></typeparam> public interface ICustomerListIn<in T> { //T Get();//不能作为返回值 void Show(T t); }
public interface IMyList<in inT, out outT> { void Show(inT t); outT Get(); outT Do(inT t); ////out 只能是返回值 in只能是参数 //void Show1(outT t); //inT Get1(); } public class MyList<T1, T2> : IMyList<T1, T2> { public void Show(T1 t) { Console.WriteLine(t.GetType().Name); } public T2 Get() { Console.WriteLine(typeof(T2).Name); return default(T2); } public T2 Do(T1 t) { Console.WriteLine(t.GetType().Name); Console.WriteLine(typeof(T2).Name); return default(T2); } }
泛型缓存(选修)
/// <summary> /// 字典缓存:静态属性常驻内存 /// </summary> public class DictionaryCache { private static Dictionary<string, string> _TypeTimeDictionary = null; static DictionaryCache() { Console.WriteLine("This is DictionaryCache 静态构造函数"); _TypeTimeDictionary = new Dictionary<string, string>(); } public static string GetCache<T>() { Type type = typeof(T); if (!_TypeTimeDictionary.ContainsKey(type.Name)) { _TypeTimeDictionary[type.Name] = string.Format("{0}_{1}", typeof(T).FullName, DateTime.Now.ToString("yyyyMMddHHmmss.fff")); } return _TypeTimeDictionary[type.Name]; } } /// <summary> /// 每个不同的T,都会生成一份不同的副本 /// 适合不同类型,需要缓存一份数据的场景,效率高 /// 不能清除 /// </summary> /// <typeparam name="T"></typeparam> public class GenericCache<T> { static GenericCache() { //Console.WriteLine("This is GenericCache 静态构造函数"); _TypeTime = string.Format("{0}_{1}", typeof(T).FullName, DateTime.Now.ToString("yyyyMMddHHmmss.fff")); } private static string _TypeTime = ""; public static string GetCache() { return _TypeTime; } }