位置:首页 > 软件操作教程 > 编程开发 > C# > 问题详情

C# 变体

提问人:刘团圆发布时间:2020-12-08

    变体(variance)是协变(covariance)和抗变(contravariance)的统称,这两个概念在.NET4中引入。实际上,它们己经存在了较长时间了(在.NET 2.0中就可以使用),但在.NET 4之前很难实现它们,因为它们需要定制的编译过程。

    要掌握这些术语的含义,最简单的方式是把它们与多态性进行比较。多态性允许把派生类型的对象放在基类型的变量中,例如:

Cow myCow = new Cow("BenM>

Animal myAnimal = myCow;

    其中把Cow类型的对象放在Animal类型的变量中,这是可行的,因为Cow派生自Animal。

    但这不适用于接口,也就是说,下面的代码不能工作:

IMethaneProducer<Cow> cowMethaneProducer = myCow;

IMethaneProducer<Animal> animalMethaneProducer = cowMethaneProducer;

    假定Cow支持IMethaneProducer<Cow>接口,第一行代码就没有问题。但是,第二行代码预先假定两个接口类型有某种关系,但实际上这种关系不存在,所以无法把一种类型转换为另一种类型。可以在泛型接口和泛型委托上定义变体类型参数,以适合上述代码演示的情形。

    为使上述代码工作,IMethaneProducer<T>接口的类型参数T必须是协变的。有了协变的类型参数,就可以在IMethaneProducer<Cow>和IMethaneProducer<Animal>之间建立继承关系,这样一种类型的变量就可以包含另一种类型的值,这与多态性类似(但稍复杂些)。

    为了完成对变体的介绍,需要看看变体的另一面:抗变。抗变和协变是类似的,但方向相反。抗变不能像协变那样,把泛型接口值放在使用基类型的变量中,但可以把该接口放在使用派生类型的变量中,例如:

    IGrassMuncher<Cow> cowGrassMuncher = myCow;

    IGrassMuncher<SuperCow> superCowGrassMuncher = cowGrassMuncher;

初看起来似乎有点古怪,因为不能通过多态性完成相同的功能。但是这在一些情况下是一项有效的技术。

继续查找其他问题的答案?

相关视频回答
回复(0)
返回顶部