协变:
和谐的变化,自然的变化
因为里氏替换原则,父类可以装子类,所以子类变父类
比如 string 变成 object,感受是和谐的
逆变:
逆常规的变化,不正常的变化
因为里氏替换原则 父类可以装子类 但是子类不能装父类,所以父类变子类
比如 object 变成 string,感受是不和谐的
协变和逆变是用来修饰泛型的
协变:out
逆变:in
用于在泛型中修饰泛型字母的,只有泛型接口和泛型委托能使用
// 作用 // 1.返回值 和 参数
// 用out修饰的泛型 只能作为返回值
internal delegate T TestOut<out T>(); // 用in修饰的泛型 只能作为参数
internal delegate void TestIn<in T>(T t); // 2.结合里氏替换原则理解
internal class Father { } internal class Son : Father { } internal class Program
{ private static void Main(string[] args) { Console.WriteLine("协变逆变"); // 作用(结合里氏替换原则理解) // 协变 父类总是能被子类替换 // 看起来 就是 son ——> father TestOut<Son> os = () => new Son(); TestOut<Father> of = os; Father f = of(); // 实际上 返回的 是os里面装的函数 返回的是Son // 逆变 父类总是能被子类替换 // 看起来像是 father——>son 明明是传父类 但是你传子类 不和谐的 TestIn<Father> iF = value => { }; TestIn<Son> iS = iF; iS(new Son()); // 实际上 调用的是 iF }
}
协变 out
逆变 in
用来修饰泛型替代符,只能修饰接口和委托中的泛型
作用两点:
- out 修饰的泛型类型只能作为返回值类型 ,in 修饰的泛型类型只能作为参数类型
- 遵循里氏替换原则,用 out 和 in 修饰的泛型委托,可以相互装载(有父子关系的泛型)
协变:父类泛型委托装子类泛型委托
逆变:子类泛型委托装父类泛型委托