1.什么是泛型?
就是在声明的时候,带上一个<>,指定类型参数,调用的时候指定类型调用。泛型可以有“泛型方法”,“泛型类”,“泛型接口”,“泛型委托”。
2.泛型的原理:
编译.png1.)泛型在编译之后,泛型参数会生成占位符`;
2.)“CLR\JIT”根据不同的调用,生成不同的普通方法;
3.)泛型不是语法糖,是框架的升级所支持的;
3.泛型缓存:
泛型缓存本质是一个泛型类,泛型类会根据调用的不同类型生成不同的副本;
public class GenericCache<T>
{
static GenericCache()
{
Console.WriteLine("This is GenericCache 静态构造函数");
_TypeTime = $"{typeof(T).FullName}_{DateTime.Now.ToString("yyyyMMddHHmmss.fff")}";
}
private static string _TypeTime = "";
public static string GetCache()
{
return _TypeTime;
}
}
4.泛型的约束:
约束可分为:基类约束,接口约束,引用类型约束,值类型约束,无参数构造函数约束。
//基类约束
public static void Show<T>(T tParameter)
where T : BaseClasee{}
//接口约束
public static void Show<T>(T tParameter)
where T : ISports{}
//引用类型约束
public static void Show<T>(T tParameter)
where T : class{}
//值类型约束
public static void Show<T>(T tParameter)
where T : struct{}
//无参数构造函数约束
public static void Show<T>(T tParameter)
where T : new(){}
5.泛型的协变和逆变:
为了架构层面上可能会产生类型安全的问题,所以引入协变和逆变。
协变: Out 只能做返回值 ,不能做参数,其实是一种为了避开风险而存在的一种约束;
public interface ICustomerListOut<out T>
{
T Get();
}
public class CustomerListOut<T> : ICustomerListOut<T>
{
public T Get()
{
return default(T);
}
}
逆变:In 只能做参数 ,不能做返回值,其实是一种为了避开风险而存在的一种约束;
public interface ICustomerListIn<in T>
{
void Show(T t);
}
public class CustomerListIn<T> : ICustomerListIn<T>
{
public void Show(T t)
{
}
}
为了更好理解“协变”和“逆变”,我们首先定义两个类分别为父类Animal及子类Cat;
//父类接口初始化子类实例时,父类对象无法调用子类方法所以T只能为返回值不能为参数称之为协变
ICustomerListOut<Animal> customerList2 = new CustomerListOut<Cat>();
//子类接口初始化父类实例时,子类对象可以调用父类方法但返回对象未必为父类所以T只能为参数不能为返回值称之为逆变
ICustomerListIn<Cat> customerList1 = new CustomerListIn<Animal>();
以上“协变”,“逆变”为个人理解,大家有不同的理解可以评论区留言相互探讨;
网友评论