介绍

  • 协变(out):
    • 和谐、自然的变化
    • 里式替换原则中,父类容器可以装载子类对象,子类可以转换成父类
    • 比如string转object,感受是和谐的
  • 逆变(in):
    • 逆常规、不正常的变化
    • 里式替换原则中,父类容器可以装载子类对象,但是子类对象不能装载父类
    • 所以父类转换为子类,比如object转string,感受是不和谐的
  • 协变和逆变是用来修饰泛型的,用于泛型中修饰字母,只有泛型接口和泛型委托能使用

作用

//1.限定泛型的返回值与参数的位置
//协变:用out修饰的泛型,只能作为返回值
delegate T TestOut<out T>();
//逆变:用in修饰的泛型,只能作为参数
delegate T TestIn<in T>(T t);
​
//2.结合里式替换原则,用out in修饰的泛型委托可以相互装载(有父子关系)
class Father{}
class Son:Father{}
​
class Program
{
    static void Main(string[] args)
    {
        //协变,父类总是能被子类替换
        TestOut<Son> oS = () => 
        {
            return new Son();
        };
        TestOut<Father> oF = oS;
        //实际上返回的是oS里面装的Son函数
        Father f = of();
        
        //逆变,父类总是能被子类替代
        TestIn<Father> iF = (value) =>{};
        TestIn<Son> iS = iF;
        //实际上调用的是iF
        iS(new Son());
    }
}

资料参考

https://www.bilibili.com/video/BV1Ar4y1K7AK?p=21