C#抗变和协变

从.NET3.5开始 加入了这两个概念。在4.0中更是加强了

这里就这两个概念做一个分析

委托调用的方法不需要与委托声明定义的类型相同。因此可能出现协变和抗变。

1. 返回类型协变

方法的返回类型可以派生于委托定义的类型。在下面的示例中,委托MyDelegate定义为返回DelegateReturn类型。赋予委托实例d1的方法返回DelegateReturn2类型,DelegateReturn2派生自DelegateReturn,因此满足了委托的需求。这称为返回类型协变

public class DelegateReturn
{
}
public class DelegateReturn2 : DelegateReturn
{
}

public delegate DelegateReturn MyDelegate1();//定义的委托 返回值是父类

class Program
{
static void Main()
{
MyDelegate1 d1 = Method1;
d1();
}

static DelegateReturn2 Method1()//但是实际函数返回的是子类
{
DelegateReturn2 d2 = new DelegateReturn2();
return d2;
}
}

可以看出 协变是指调用函数的返回类型是 委托的返回类型的子类

2. 参数类型抗变

术语"参数类型抗变"表示,委托定义的参数可能不同于委托调用的方法。这里是返回类型不同,因为方法使用的参数类型可能派生自委托定义的类型。在下面的示例代码中,委托使用的参数类型是DelegateParam2,而赋予委托实例d2的方法使用的参数类型是DelegateParam,
DelegateParam是DelegateParam2的基类。

public class DelegateParam
{
}
public class DelegateParam2 : DelegateParam
{
}
public delegate void MyDelegate2(DelegateParam2 p);//参数是子类
class Program
{
static void Main()
{
MyDelegate2 d2 = Method2;
DelegateParam2 p = new DelegateParam2();
d2(p);
}
static void Method2(DelegateParam p)//实际参数是父类
{
}
}

抗变就是指 实际函数的参数用的是子类,但是委托是父类的参数
总结一句好记的话“参抗用小的,返协用大的”----->实际参数  抗变 用子类(辈分小)调用(委托),实际返回值  协变 用父类(大辈分)。。。。

Delegate object  AAA(string s);//委托的 返回父类,参数子类



string method(object o);//函数 返回子类,参数父类



AAA a=new AAA(method);//委托方法  正确 

  

但是在.NET3.5中的抗变协变 都只能对于数组和接口使用,不能用于泛接口。但是在.NET4.0中是可以的。。。

推荐帖子:http://www.cnblogs.com/Ninputer/archive/2008/11/22/generic_covariant.html

你可能感兴趣的:(C#)