在C#中,协变与逆变适用于修饰1泛型委托或是泛型接口的,协变的关键字为out,逆变的关键字为in,添加了out的泛型只能作为返回值来使用,添加了in关键字的泛型只能作为参数来使用。此外,添加了协变与逆变关键字的泛型委托也可以实现类似于里氏替换原则的父子类容器间的互相装载转化。
cs
namespace lesson17
{
delegate T TestOut<out T>();//添加了协变修饰符的泛型只能作为返回值
delegate void TestIn<in T>(T v);//添加了逆变修符的泛型只能作为参数
//协变与逆变也可以用在泛型接口中,同样遵循各自的规则
interface Test<out T>
{
T TestFun();
}
class Father { }
class Son : Father { }
internal class Program
{
static void Main(string[] args)
{
//添加了协变的泛型委托可以自动利用里氏替换原则原则,用指定为父类的委托去装载指定为子类的委托
//即为父类总是能被子类替换,实现由子类到父类的转化
TestOut<Son> os = () => { return new Son(); };
TestOut<Father> of = os;
Father f = of();//用Father父类装载,实际返回了Son()对象
//添加了逆变的泛型委托可以自动利用里氏替换原则原则,用指定为子类的委托去装载指定为父类的委托
//即为子类总是能被父类替换,实现由父类到子类的转化
TestIn<Father> iF = (value) => { };
TestIn<Son> iS = iF;
iS(new Son());//传入了子类对象作为参数,实际调用的是父类委托iF中的逻辑
}
}
}