当你看到这个标题的时候,是不是会有疑惑呢?不过,没关系,接下来,你就会知道原因了。
首先,我们还是先来看看委托的定义吧!
委托是一种引用方法的类型。delegate关键字用于声明一个引用类型,该引用类型可用于封装
命名方法或匿名方法。一旦为委托分配了方法,委托将与该方法具有完全相同的行为。委托方法的调用
可以像其他任何方法一样,具有参数和返回值。
换句话说,就是委托是承载方法用的,这个方法可以是静态方法,也可以是实例方法(非静态
)。接下来呢,我们就来看看这个委托都有哪些东西需要我们去关注吧!
既然委托时承载方法的,那么我们就可以把它当成一个方法来用了,直接用委托名加小括号来
调用方法。如下:
public delegate void DL(int i);//像方法一样定义委托
//定义和委托具有相同签名的方法
public void FF(int i)
{
Console.WriteLine(i);
}
然后,在main方法中调用:
Program p = new Program();
DL dl = new DL(p.FF);//这样 委托就和方法一样了,当然,还有一种调用的方法,让委托的
方法直接等于一个方法DL dl1 = p.FF;
dl(100);//dl 是一个变量 ,但是它具有和方法一样的功能
通过委托呢,我们还可以实现一个方法调用另一个方法:
static void DY(DL dl)//将委托当形参用
{
dl(200);
}
则,在main方法中就可以这么调用:
DY(dl);
如果你熟悉匿名方法的话,就应该知道,在匿名方法定义的时候,委托也是必不可少的:
DL dl2 = delegate(int i)//匿名方法的声明
{
Console.WriteLine(i);
};//注意了,这个时候,我们把它看成是一条语句,需要加分号来结束的
委托还能实现类与类之间方法的调用,可以将定义的委托当成方法中的参数。如下:
我们先定义一个MyClass类
class MYClass
{
public void Method(Program.DL dl)//通过类名来调用在另一个类中定义的委托
{
dl(500);
}
}
然后,这样调用:
MYClass mc = new MYClass();
mc.Method(dl);//在这里,在类MYClass的Method方法调用了类Program中的方法
同时,委托还有多播的功能,什么意思呢,就是通过对一个委托方法传值,让与其关联的委托
方法都能够接受到这个值。
DL dl3 = dl1 + dl2;//相当于是将实参分别传给了dl1和dl2,可以同时调用多个委托
dl3(600);
这样,就把600这个值分别传给了dl1和dl2这两个委托,它们就接收了相同的参数值。
还有就是委托中比较重要的两个概念――协变和逆变。
它们的本质就是类中的赋值,子类型赋给父类型,做了一个类型转换。
要想理解这两个概念,我们还在下面的例子中体现吧!
首先,我们定义两个类:
class Phone//父类型
{
}
class Mobile : Phone//子类型
{
}
接下来,我们在main方法外面定义几个方法:
public Phone GetPhone()
{
return new Phone();
}
public Mobile GetMobile()
{
return new Mobile();
}
public void GetnewPhone(Phone p)
{
}
public void GetnewMobile(Mobile m)
{
}
然后,就可以在main方法中调用了:
//协变:本质是在方法调用结束后,再进行赋值操作,即发生类型转换――子类型转换成父
类
DLPhone dlp = p.GetMobile;//子类型phone赋给父类型mobile,完成了类型转换的操作
DLPhone dlp1 = p.GetPhone;//正常赋值,mobile赋给mobile
Console.WriteLine(dlp.GetType().ToString());
//逆变:本质是在方法调用过程中,其参数之间进行赋值,即发生类型转换――子类型转
换成父类
DLMobile dlm = p.GetnewPhone;
DLMobile dlm1 = p.GetnewMobile;
要弄清一点,发生类型转换的地方,协变是方法的返回值的一个赋值(发生类型转换),而逆
变是方法中参数的一个赋值(发生类型转换)。
总结一下,委托呢,它具有普通方法的功能,具有类中子类与父类赋值的功能,具有当形参的
功能,还有定义匿名方法的功能等。这样的话,它是不是有点变态呢!