前言
协变与抗变,听名字挺高大上的,其实无非就是类之间继承关系导致的一些基本问题。
我们先举个例子,首先我们有两个类,代码如下:
public class Shape
{
public double Width { get; set; }
public double Height { get; set; }
public override string ToString()
{
return string.Format("Height:{0},Width:{1}", Height, Width);
}
}
public class Rectangle:Shape
{
}
- 如果现在有一个方法:
public void Display(Shape shape) { }
,这个方法能不能传入一个Rectangle的对象呢?答案是可以,因为参数类型是协变的,通俗来讲就是可以用子类对象代替父类参数。 - 如果有一个方法:
public Rectangle ReturnValue(){ }
需要返回一个父类的对象,可以用子类代替么?答案是不可以,因为返回值类型是抗变的,方法不能保证父类Shaper拥有所有子类Rectangle的特性,反过来可以。
这里总结一下:
通常我们在设计参数和返回值都有一个原则,参数要尽可能“泛”,返回值要尽可能的“细”。泛,指得是用接口或者父类作为参数,这样可以接收更多的参数类型;细,指的是返回具体类型,这样可以更好说明方法的作用。
但是在接口不同于以上两者,所以引入两个关键字out和in来标识抗变和协变。
网友评论