一、泛型方法
static void Main(string[] args)
{
string hello = "hello";
Console.WriteLine(Type(hello));
Console.ReadKey();
}
public static string Type<T>(T t)
{
return t.GetType().Name;
}
二、泛型类
方法一:通过反射创建泛型实例
public class Student
{
public string Name { get; set; }
}
// 对该类加上约束,限定T类型只能是Student或Student的子类
public class StudentHelper<T> where T:Student
{
public T GetStudent()
{
// 通过反射创建T的实例,注意不能使用default(T),因为此时default(T)值是null;
T t = (T)Activator.CreateInstance(typeof(T));
// 因为使用了约束,所以能根据约束类型使用它的属性
t.Name = "张三";
return t;
}
}
方法二:.通过约束创建泛型实例
public class WomanHelper<T,S> where T : new()
{
public T GetStudent()
{
// 如果不想使用反射创建实例,则必须加上new约束,才能通过new创建实例
T t = new T();
return t;
}
}
三、逆变协变
协变:被定义的协变泛型T,只能作为方法的返回值,不能作为方法的参数;
逆变:被定义的逆变泛型T,只能作为方法的参数,不能作为方法的返回值;
internal class Program
{
static void Main(string[] args)
{
// List<Person> list = new List<Student>(); 错误,因为List<T>和List<T2>是两种类型
// 该赋值正确,是因为IEnumerable支持协变
IEnumerable<Person> list2 = new List<Student>();
// 协变,子类泛型变量可以通过协变赋值给父类泛型变量
IMyOut<Person> per = new MyOut<Student>();
Person s = per.GetT();
// 逆变,父类泛型变量的泛型类可以通过逆变赋值给子类泛型变量的泛型类
IMyIn<Student> stu = new MyIn<Person>();
stu.GetT(new Student
{
Name = "zhangsan"
});
Console.ReadKey();
}
}
public class Person
{
public string Name { get; set; }
}
public class Student : Person
{
}
#region 协变定义
interface IMyOut<out T>
{
T GetT();
}
class MyOut<T> : IMyOut<T>
{
// 协变的泛型变量只能做返回值;
public T GetT()
{
return default(T);
}
}
#endregion
#region 逆变定义
interface IMyIn<in T>
{
void GetT(T t);
}
class MyIn<T> : IMyIn<T>
{
// 逆变的泛型变量只能做参数;
public void GetT(T t)
{
}
}
#endregion