泛型是 2.0 版 C# 语言和公共语言运行库 (CLR) 中的一个新功能。泛型将类型参数的概念引入 .NET Framework。
类型参数使得设计如下类和方法成为可能:这些类和方法将一个或多个类型的指定推迟到客户端代码声明并实例化该类或方法的时候。例如,通过使用泛型类型参数 T,您可以编写其他客户端代码能够使用的单个类,而不致引入运行时强制转换或装箱操作的成本或风险。
转换为白话文就是,当定义 类变量、函数参数 的时候,可以不使用具体的类型,而是使用 T 表示,T 哪个具体的类型,在程序运行的时候才能够确定
如,定义类变量
private T t;
如定义函数参数
public void Add(T t)
{
_cowList.Add(t);
}
// 规定泛型类 T 必须继承抽象类 Animal
public void Breathe<T>(T t) where T : AnimalAb
{
t.Breathe();
}
// 规定泛型类 T 必须继承接口 IMove
public void Move<T>(T t) where T : IMove
{
t.Move();
}
如上,我们可以规定 T 是继承 某个接口 或者 某个类,或者不做任何限制
在编码阶段,我们并不知道真正运行的时候,传递过来的参数或者实例化的对象是哪个具体的类,
如 Move 方法中传递进来的参数可以是任何继承于 IMove 接口的类对象
Breathe 方法中传递进来的参数可以是任何继承于 Animal 抽象类的对象
代码实现如下
using System.Collections.Generic;
// 定义抽象类
public abstract class AnimalAb
{
// 定义抽象方法
public abstract void Breathe();
}
// 定义接口
public interface IMove
{
void Move();
}
// 具体对象类继承抽象类和接口
public class Cow : AnimalAb, IMove
{
// 实现抽象方法
public override void Breathe()
{
// 用鼻子呼吸
}
// 实现接口规定的方法
public void Move()
{
// 四条腿走路
}
}
// 具体对象类继承抽象类和接口
public class Fish : AnimalAb, IMove
{
// 实现抽象方法
public override void Breathe()
{
// 用鳃呼吸
}
// 实现接口规定的方法
public void Move()
{
// 用尾巴游泳
}
}
public class AnimalController
{
// 规定泛型类 T 必须继承抽象类 Animal
public void Breathe<T>(T t) where T : AnimalAb
{
t.Breathe();
}
// 规定泛型类 T 必须继承接口 IMove
public void Move<T>(T t) where T : IMove
{
t.Move();
}
}
public class CowFarm<T> where T : Cow
{
private T t;
private List<T> _cowList = new List<T>();
public void Add(T t)
{
_cowList.Add(t);
}
}
适用范围:
当有多个类 继承 同一个 类、抽象类、接口 的时候,使用泛型规定传递的参数或者变量,可以避免过多实现重载方法
如不使用泛型, AnimalController 代码中的 Move 方法,需要分别定义 传递 Cow 类型参数的方法,传递 Fish 类型参数的方法,如下
public void Move(Cow cow)
{
}
public void Move(Fish fish)
{
}
如果使用多个重载方法,当需要 添加新的子类型 或者 删除已有类型 时,都需要修改 AnimalController l类