C#协变和逆变

2021-04-20 11:27

阅读:486

C#种的协变和逆变只能针对泛型的接口和委托。在C#1的时候委托是支持参数的协变和逆变的。

协变和逆变本质上是针对类型和类型之间的绑定的。比如说数组,数组其实就是一种和具体类型之间发生绑定的类型。数组类型Int32[]就对应于Int32这个原本的类型。任何类型T都有其对应的数组类型T[]。我们说:如果有类型Parent和其子类Sub,那么Parent p=new Sub();这种的类型转换是安全的。如果有一种类型和Parent类型进行了绑定,比如说Parent[]数组,如果Sub[]到Parent[]的转换是安全的,我们就说是协变,如果相反的方向上转换是安全的,我们就说是逆变了。C#中我们知道数组是协变的,也就是说Sub[]到Parent[]的转换是安全的。再举个例子,就是String类型继承自Object类型,所以任何String的引用都可以安全地转换为Object引用。我们发现String[]数组类型的引用也继承了这种转换能力,它可以转换成Object[]数组类型的引用,数组这种与原始类型转换方向相同的可变性就称作协变(covariant

由于数组不支持反变性,我们无法用数组的例子来解释反变性,所以我们现在就来看看泛型接口和泛型委托的可变性。假设有这样两个类型:TSub是TParent的子类,显然TSub型引用是可以安全转换为TParent型引用的。如果一个泛型接口IFoo,IFoo可以转换为IFoo的话,我们称这个过程为协变,而且说这个泛型接口支持对T的协变。而如果一个泛型接口IBar,IBar可以转换为T的话,我们称这个过程为反变(contravariant而且说这个接口支持对T的反变。因此很好理解,如果一个可变性和子类到父类转换的方向一样,就称作协变;而如果和子类到父类的转换方向相反,就叫反变性。

 


评论


亲,登录后才可以留言!