C# 协变与抗变

之前在编写程序的过程中,遇到了这个概念。

在.NET 4之前,泛型接口是不变的。.NET 4通过协变和抗变为泛型接口和泛型委托添加了一个重要的扩展。协变和抗变指对参数和返回值的类型进行转换。例如,可以给一个需要Shape参数的方法传送Rectangle参数码?下面用示例说明这些扩展的优点。

在.NET中,参数类型是协变的。假定有Shape和Rectangle类,Rectangle派生自Shape基类。声明Display()方法是为了接受Shape类型的对象作为其参数:

public void Display(Shape o) { }   //形参是基类,实参是派生类  这是协变   ,就是说本来预想要个 10  结果人家给了个100,当然可以接受了-。-

现在可以传递派生自Shape基类的任意对象。因为Rectangle派生自Shape,所以Rectangle满足Shape的所有要求,编译器接受这个方法调用:

Rectangle r = new Rectangle { Width= 5, Height=2.5};  
Display(r);

方法的返回类型是抗变的。当方法返回一个Shape时,不能把它赋予Rectangle,因为Shape不一定总是Rectangle。反过来是可行的:如果一个方法像GetRectangle()方法那样返回一个Rectangle,

public Rectangle GetRectangle();  //返回值类型是派生类,结果返回的是基类,可以 就是说 我可以给出100,结果你只需要10,当然可以  反过来就不行了

就可以把结果赋予某个Shape:

Shape s = GetRectangle(); 

在.NET Framework 4版本之前,这种行为方式不适用于泛型。在C# 4中,扩展后的语言支持泛型接口和泛型委托的协变和抗变。下面开始定义Shape基类和Rectangle类:

public class Shape  
{
public double Width { get; set; }
public double Height { get; set; }
public override string ToString()
{
return String.Format("Width: {0}, Height: {1}", Width, Height);
}
}
public class Rectangle: Shape
{
}





posted @ 2011-09-28 08:56  Tammie-锴  阅读(1908)  评论(1编辑  收藏  举报