简要介绍:
协变和抗变指对参数和返回值进行转换;
协变:按照继承链正向改变(实际上是向上兼容:子类向父类的转化)
逆变:按照继承链反向改变(实际上是向下兼容:父类向子类的转化)
下面说一下具体使用方式(在.net4之前,泛型接口没有协变和抗变)
一.不使用泛型接口的情况
//.net 参数类型是协变的返回类型是抗变的
public class Shape
{
public int Width { get; set; }
public int Height { get; set; }
}
public class Rectangle : Shape
{
}
public interface RSInterface
{
void Display(Shape o);
Rectangle GetRectangle();
}
public class RSClass : RSInterface
{
public int Rwidth { get; set; }
public int Rheight { get; set; }
public RSClass() { }
public RSClass(int width, int height)
{
this.Rwidth = width;
this.Rheight = height;
}
/// <summary>
/// 实现协变操作
/// </summary>
/// <param name="o"></param>
public void Display(Shape o)
{
Console.WriteLine($"width:{o.Width};height:{o.Height}");
}
/// <summary>
/// 实现抗变操作
/// </summary>
/// <returns></returns>
public Rectangle GetRectangle()
{
Rectangle rectangle = new Rectangle();
rectangle.Width = this.Rwidth;
rectangle.Height = this.Rheight;
return rectangle;
}
}
//控制台输出
RSInterface rS = new RSClass(26, 15);
//协变
rS.Display(new Rectangle { Width = 5, Height = 4 });
//抗变
Shape shape = rS.GetRectangle();
Console.WriteLine($"width:{shape.Width};height:{shape.Height}");
Console.ReadLine();
二.使用泛型接口的情况(使用out关键字代表协变,使用in关键字代表抗变)
public class Shape
{
public int Width { get; set; }
public int Height { get; set; }
}
public class Rectangle : Shape
{
}
public interface RSInterface<in Shape, out Rectangle>
{
void Display(Shape o);
Rectangle GetRectangle();
}
public class RSClass : RSInterface<Shape, Rectangle>
{
public int Rwidth { get; set; }
public int Rheight { get; set; }
public RSClass() { }
public RSClass(int width, int height)
{
this.Rwidth = width;
this.Rheight = height;
}
/// <summary>
/// 抗变 向下兼容
/// </summary>
/// <param name="o"></param>
public void Display(Shape o)
{
Console.WriteLine($"width:{o.Width};height:{o.Height}");
}
/// <summary>
/// 协变 向上兼容
/// </summary>
/// <returns></returns>
public Rectangle GetRectangle()
{
Rectangle shape = new Rectangle();
shape.Height = this.Rheight;
shape.Width = this.Rwidth;
return shape;
}
}
//控制台输出
RSInterface<Rectangle,Shape> rS = new RSClass(26, 15);
//抗变
rS.Display(new Rectangle { Width = 5, Height = 4 });
//协变
Shape shape = rS.GetRectangle();
Console.WriteLine($"width:{shape.Width};height:{shape.Height}");
Console.ReadLine();