0%

【C#】泛型

泛型指一种模具,将相对应的数据注入即可得到泛型指定类型

①泛型类

//这是一个宠物笼子模型
class Cage{ //填充对应的宠物类型即可得到专属的笼子
T[] petsArry; //T是一个替代值,就像形参,亦可定义多个
public void PutIn(T pet){…}
public T TakeOut(int index){…}
}

//调用时
var dogCage = new Cage();
var cavyCage = new Cage();
//Dog、Cavy是两个类
//var是一个简写,当然也可以写成Cage与Cage
dogCage.PutIn(new Dog());//放入第一只狗
dogCage.PutIn(new Dog());//放入第二只狗
Dog dog=dogCage.TakeOut(0);//取出第一只狗

代码示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
class Pet { }
class Dog : Pet { }
class Cat : Pet { }
class Cage
{ //填充对应的宠物类型即可得到专属的笼子
T[] petsArry; //T是一个替代值,就像形参
private int num = 0;
public void PutIn(T pet)
{
if (num < petsArry.Length) petsArry[num++] = pet;
else Console.WriteLine("笼子已满");
}

public T TakeOut(int index)
{
return petsArry[index];
}

public Cage(int num)
{
petsArry=new T[num];
}
}

class Program
{
static void Main(string[] args)
{
var dogCage = new Cage(2);
dogCage.PutIn(new Dog());
dogCage.PutIn(new Dog());
Dog dog=dogCage.TakeOut(0);
}
}

关键字dufault

返回指定类的默认值。如果泛型中需要对初始化却又不能确定泛型中注入的类型就可以使用该关键字将其初始化为默认值。 即

引用类型→null 数值类型→0 bool→false char→‘\\0’ enum→相关枚举值对应0的值(第一个)

为什么需要泛型类?

用基类或者公共的接口,甚至是所有类的基类object,也可以实现一个cage类,但是类型太宽泛,需要显示转换类型,并且判断真实类型是什么。

泛型类的优势: ⚪代码量更小,无论多少种笼子,我们只需要一个实现 ⚪只有需要的类型才会被实例化 ⚪易于维护,修改模板,所有的实例都将改变

②泛型方法

泛型方法就是方法的模型,给定具体的类型,就可以实例化出一个操作该类型的具体方法。

→泛型类中往往有泛型方法,普通类中也可以由泛型方法。

class Dog{
void DogIsHappy(T target){…}
//定义让狗狗开心的函数,即使狗狗开心,大括号内部为具体行为

}

class Ball{…}//定义“球”类

//Main函数中(调用时)
Dog dog =new dog();//实例化一个狗狗对象
dog.IsHappy(new Person);//定义狗狗遇到球就开心
dog.IsHappy(3);//定义狗狗遇到数字3就开心

③约束

控制泛型,缩小泛型参数的范围

→无论多么广泛总要有个范围,范围越小,约好控制 →泛型类、泛型方法都可被约束

约束条件:

类名该类或者继承该类的类 class任何struct任何接口名该接口类型或任何实现该接口的类型 new()→带有无参共有构造函数的类

约束叠加规则 泛型语句 where T 主约束 + 接口约束 + 构造约束 →层层递进,逐层收紧。 主约束:只能有一个,包括类名,class,struct 接口约束:任意多个 T 为参数,视实际情况替换 如:

1
2
void Cage where T:Pet,IClimbTree,new(){...}
//T必须是Pet类或由Pet类派生的类,且接受接口IClimbTree,且构造函数为无参。

④泛型接口

泛型接口允许我们将接口成员的参数返回类型设置为泛型参数的接口

//定义泛型接口
interface IMyself{
T Myself(T self);
}
//实现泛型接口
class A:IMyself{
public A Myself(A self);
}//类型参数可以是实现类本身或者是其他类型