定义:
委托是一种在对象里保存方法引用的类型,同时也是一种类型安全的函数指针。
理解委托的一种方式可以把委托的作用当作是给方法签名指定名称。
委托的定义类似于方法的定义,但没有方法体,定义的委托名前要加上关键字delegate。
因为定义委托基本上是定义一个新类,所以可以在定义类的任何地方定义委托,既可以在另一个类的内部定义委托,也可以在所有类的外部定义委托,还可以在命名空间中把委托定义为顶层对象。根据定义的可见性,可以在委托定义上添加一般的访问修饰符:public、private和protected等:
一个委托实例压缩(或者称为封装)了一个方法称之为“一个可调用的实体” ,所以“一个可调用的实体”也就由这个委托实例本身和实例中封装的方法组成
委托也可以包含多个方法,这种委托称为多播委托。
如果调用多播委托,就可以按顺序连续调用多个方法。为此,委托的签名就必须返回 void (否则,返回值应送到何处?)(当委托只包含一个方法的时候,其返回类型的声明可以参照所封装的方法,不一定必须是void)。实际上,如果编译器发现某个委托返回 void ,就会自动假定这是一个多播委托。
委托的优点:
(1)压缩方法的调用。
(2)合理有效地使用委托能提升应用程序的性能。
(3)用于调用匿名方法。
多播委托:
(1)多播委托包含一个以上方法的引用。
(2)多播委托包含的方法必须返回void,否则会抛出run-time exception。
多播委托的示例程序:
using System;
using System.Collections.Generic;
using System.Text;
namespace ConsoleApp1
{
//声明一个委托
public delegate void msg();
//编写一个类
class messges
{
//messges类下的一个成员方法m1
public static void m1()
{ Console.WriteLine("方法一被huashanlin调用"); }
//messges类下的一个成员方法m2
public static void m2()
{ Console.WriteLine("方法二被huashanlin调用"); }
//messges类下的一个成员方法m3
public static void m3()
{ Console.WriteLine("方法3huashanlin被调用"); }
}
//另一个类
class Program
{
//该类下包含的主函数
static void Main(string[] args)
{
//实例化一个委托,并封装messges类中的一个方法m2
msg ms = new msg(messges.m2);
//在原有的封装了一个m1方法的委托实例中再封装进一个新的方法m1
ms = ms + messges.m1;
//或者上面的语句可以写成ms += messges.m1;两者的效果是一样的
//以下为该委托实例封装第三个方法
ms += messges.m3;
//调用该委托实例,那么由于多播委托之后调用该委托就要执行完此封装进去的三个方法
ms();
}
}
}
//注:deletge保存的方法签名是以hash队列的形式存在的
多播委托示例程序二:
delegate void Delegate_Multicast(int x, int y);
Class Class2
{
static void Method1(int x, int y) {
Console.WriteLine("You r in Method 1");
}
static void Method2(int x, int y) {
Console.WriteLine("You r in Method 2");
}
public static void Main()
{
Delegate_Multicast func = new Delegate_Multicast(Method1);
func += new Delegate_Multicast(Method2);
func(1,2); // Method1 and Method2 are called
func -= new Delegate_Multicast(Method1);
func(2,3); // Only Method2 is called
}
}
解析:
上面的示例程序分别定义了名为method1 和 method2的两个接受整型参数、返回类型为void的方法。
在Main函数里使用下面的声明创建委托对象:
Delegate_Multicast func = new Delegate_Multicast(Method1);
然后使用+= 来添加委托,使用-=来移除委托
|