几行代码帮你搞懂C#中的协变与逆变
什么是协变与逆变?简单说就是在泛型编程中扩大和缩小使用范围, 达到灵活编程的效果. 比如可以将一个Dog类作Animal类使用, 也可以将一个Animal类作Dog类使用,下面通过几行代码来说明.
创建一个Animal类
internal class Dog:Animal
{
}
创建一个Dog类,继承自Animal类
internal class Animal
{
}
写一个Test类, 该类继承自ITest接口
public interface ITest<in TIn, out TOut>
{
void show(TIn value);
TOut Get();
}
internal class Test<T1, T2> : ITest<T1, T2>
{
public void show(T1 value)
{
Console.WriteLine(typeof(T1).Name);
}
public T2 Get()
{
Console.WriteLine(typeof (T2).Name);
return default(T2);
}
}
我们在主函数中使用
//父类: Animal子类: Dog
//协变:子类可以赋值给父类,用关键字out声明
//逆变:父类可以赋值给子类,用关键字in声明
ITest<Dog, Animal> testl = new Test<Dog, Animal>();//正常传递参数,Dog是入参,Animal是出参
ITest<Dog, Animal> test2= new Test<Dog, Dog>();//协变
ITest<Dog, Animal> test3 = new Test<Animal, Animal>();//逆变
ITest<Dog, Animal> test4 = new Test<Animal, Dog>();//逆变+协变
ITest<Animal, Dog> test5 = new Test<Animal, Dog>();//正常传递参数
/*
错误,ITest类第一个类型参数是in;代表逆变,逆变可以将父类赋值给子类,而这里却将子类赋值给父类,逻辑相悖
ITest<Animal, Dog> test6 = new Test<Dog, Dog>();
*/
/*
错误, ITest类第二个类型参数是out,代表协变,协变可以将子类赋值给父类,而这里却将父类赋值给子类,逻辑相悖
ITest<Animal, Dog> test7 = new Test<Animal, Animal>();
*/
/*
ITest类第一个类型参数是in,代表逆变,逆变可以将父类赋值给予类,而这里却将于类斌值给父类,逻辑相悖
ITest类第二个类型参数是out,代表协变,协变可以将子类赋值给父类,而这里却将父类赋值给于类,逻辑相悖
ITest<Animal, Dog> test8 = new Test<Dog, Animal>();
*/