.net 泛型
1.泛型:先声明,延迟编译。
public static void DoSome<T>(T t)
{
Console.WriteLine(t);
}
这个方法就是泛型方法,先申明参数为T,不知道具体是什么类型。
使用的时候DoSome<int>(1);
DoSome<string>("hello");
DoSome<Student>(new Student());
当使用的时候,才会具体确定传入参数是什么
优点:为了让一个方法,不同参数都可以使用。
2.有哪些?
泛型类
public class Person<T>
{
public T MyT{get;set;}
}
泛型方法
public static void DoSomeThing<T>(T t)
{
Console.WriteLine(t);
}
泛型接口public interface IBrid<T>
{
void Show(T t);
}
泛型委托
public delegate void DomeSome<T>(T t);
3.泛型约束 where 关键字
1.可以规定泛型的基类
public void SayHi<T>(T t) where T:Person
{
}
T的类型要么是基类Person,要么是Person的子类或者子孙类
2.可以规定泛型实现的接口
public void SayHi<T>(T t) where T:IBrid
{}
3.同时规定泛型实现接口和基类, 约束多个,用逗号 ,隔开
public void SayHi<T>(T t) where T : Person,IBrid
{}
4.类型约束,值类型还是引用类型
where T : new()
where T : struct
4.协变 out 逆变 in
有Animal类 有Dog类, Dog继承Animal类
Animal animal = new Animal();
Animal a1 = new Dog(); 这样没错;因为有继承关系
但是:
List<Animal> ans = new List<Animal>();正确
LIst<Animal> animals = new List<Dog>(); 这样就会报错,因为是2个不同的集合,没有继承关系
如果要是实现这个,就需要 用到逆变 out 用系统自带的IEnumerable接口
IEnumerable<Animal> ans1 = new List<Dog>();这样就可以实现了。
或者自定义一个 接口
public interface ICustomerList<out T>
{
GetT(); //协变只能是返回T
}
实现接口
public class CustomerList<T> : ICustomerList<T>
{
void GetT()
{
return default(T);
}
}
CustomerList<Animal> animals = new CustomerList<Dog>();这样就不会报错了。
反过来就是协变
List<Dog> dogs = new List<Animal>(); 这样也会报错
就需要自定义一个接口
public interface ICustList<in T >
{
void Show(T t);//逆变只能传入参数使用
}
public class CustList<T> : ICustList<T>
{
public void Show(T t)
{
Console.WriteLine(t);
}
}
CustList<Dog> dogs = new CustList<Animal>()
静态构造函数和静态属性,都是常驻内存的,第一次使用,都会一直在。
每个泛型类,都会T的不同生成新的实例。
将静态构造函数和静态属性还有泛型结合起来,就是泛型缓存。比dictionary字典静态缓存更好用的一种。