1、协变逆变
协变和逆变用来修饰泛型的
协变:out
逆变:in
用于在泛型中修饰泛型字母,只有泛型接口和泛型委托中能使用
2、作用
(1)返回值和参数
用 out 修饰的泛型,只能作为返回值
delegate T TestOut<out T>();
用 in 修饰的泛型,只能作为参数
delegate void TestIn<in T>(T t);
(2)结合里氏替换原则
class Father { } class Son : Father { }
协变:父类泛型委托装载子类泛型委托
TestOut<Son> os = () => { return new Son(); }; TestOut<Father> of = os; // 如果去掉 out 则不能直接赋值,通过 out 判断返回值是否有父子关系 Father f = of(); // 实际上返回的是 os 返回的 Son 对象 // Son s = of(); // 会报错,因为返回值要与委托的格式一致
逆变:子类泛型委托装载父类泛型委托(但其实还是满足里氏替换原则)
TestIn<Father> iF = (value) => { // 此处 value 是 Father 类型 }; TestIn<Son> iS = iF; iS(new Son()); // 实际是 Father 型的参数装载 Son 类型的数据 // 同样 iS(new Father()) 会出错,因为委托格式不一致