C#自学笔记:协变和逆变
协变和逆变
- 协变:和谐的变化
- 因为里氏替换原则父类可以装子类
- 所以子类变成父类
- 比如 string 变成 object
- 逆变:逆常规的变化
- 因为里氏替换原则父类可以装子类,但是子类不能装父类
- 所以父类变成子类
- 比如 object 变成 string
- 协变和逆变是用来修饰泛型的
- 协变:
out - 逆变:
in
- 用于在泛型中修饰泛型字母的,只有泛型接口和泛型委托能使用
- 协变:
作用
- 返回值和参数
- 用out修饰的泛型只能作为返回值
delegate T TestOut<out T>();- 用in修饰的泛型只能作为参数
delegate void TestIn<in T>(T t);
- 结合里氏替换原则理解
delegate T TestOut<out T>();
delegate void TestIn<T>(in T t);
class Father
{
}
class Son : Father
{
}
//使用
//协变,父类被子类替换 son -> father
TestOut<Son> outSon = () =>
{
return new Son();
};
TestOut<Father> outFather = outSon;
Father father = outFather();//实际上返回的是outSon里面装的函数,返回的是Son
Father father = (Father)outFather();//最终执行结果
//逆变,子类被父类替换 father -> son;
TestIn<Father> inFather = (value) =>
{
};
TestIn<Son> inSon = inFather;
inSon(new Son());//实际上调用的是inFather,传入的参数是Son,但由于value的类型是T
//所以调用inFather时要将Father转化为Son
主要作用是自动识别委托的泛型之间是否有继承关系,子类东西比父类多,所以在作返回值和参数的时候有不同的特性
TestIn<Father> inFather = Fun;
void Fun(Father value)
{
};
//Father -> Son,再调用函数
TestIn<Son> inSon = inFather;
inSon(new Son());
简单说法:out是把子类装进成父类然后输出,in是把父类as成子类然后传进来使用

浙公网安备 33010602011771号