协变与逆变(Covariance and contravariance),主要是指运行时隐式的泛型参数类型转化,协变是指子类(或实现)转化成父类(或抽象),而逆变是指父类(或抽象)转化成子类(或实现)。由子类(或实现)转化成父类(或抽象)是不会发生类型转换错误的,所以叫协变,反之,则为逆变。
例如:
View Code
public abstract class Person { //todo } public class Man : Person { //todo } public class YouthMan : Man { //todo } public class PersonBusiness { public static YouthMan Dowith(Person person) { YouthMan youthMan = new YouthMan(); //to do return youthMan; } } public class PersonClient { public static void Main() { Person person = PersonBusiness.Dowith(new Man()); // use person; } }
应从两个视角看待问题:
1、从方法的视角看:输入应当是一个宽泛的类型,代码中的Person,是一个比较宽泛的类型;输出应当是一个比较窄的子类型,例如YouthMan。这样,能够返回更精确的信息。
2、从客户端(使用者)的角度看:恰恰相反,输入参数时,可能是一个更小的类型,而输出参数则被用来作为更宽泛的用处,如代码中,返回值为YouthMan,使用时则为Person。
协变和逆变在泛型中使用时,注意两个参数的使用:out和in。
为了更好的支持泛型使用,c#4.0提供了两个参数,out和in。Out用于输出时的协变;in参数用于输入时的协变。