什么是委托
首先我们看一下微软网站对委托的定义:
委托是一种安全地封装方法的类型,它与 C 和 C++ 中的函数指针类似。与 C 中的函数指针不同,委托是面向对象的、类型安全的和保险的。
委托的定义如下:
让我们看一下上面定义委托生成的中间语言
extends [mscorlib]System.MulticastDelegate
{
} // end of class DelegateTest.AddEventHandler
委托是一个类,它定义了方法的类型。因此在任何可以声明的类的地方都可以声明委托。
委托具有以下特点:
· 委托类似于 C++ 函数指针,委托是面向对象的、类型安全的和保险的。
· 委托允许将方法作为参数进行传递。
· 委托可用于定义回调方法。
· 委托可以链接在一起;例如,可以对一个事件调用多个方法。
· 方法不需要与委托签名精确匹配(但是返回类型和参数个数及类型必须相同).
委托的作用:
1. 委托使得可以将方法当作另一个方法的参数来进行传递.
2. 委托可以绑定多个方法,这也称为多路广播。
class DelegateAndEvent
{
static void Main(string[] args)
{
DelegateAndEvent de = new DelegateAndEvent();
// Instantiate the delegate.
AddEventHandler addDelegate = de.NormalAdd;
de.Excute(3, 5, addDelegate);
Console.Read();
}
public void Excute(int a, int b, AddEventHandler addDelegate)
{
// Call the delegate.
addDelegate(a, b);
}
// Create a method for a delegate.
public void NormalAdd(int a, int b)
{
Console.WriteLine((a + b).ToString());
}
// Create other method for a delegate.
public void ExtraAdd(int a, int b)
{
Console.WriteLine((a + b + 5).ToString());
}
}
首先,我们定义一个用于加法法功能的委托AddEventHandler:
public delegate void AddEventHandler(int a,int b);
然后在客户端类DelegateAndEvent内定义两个与委托的签名(返回类型和参数)相同的方法及调用委托的方法。
public void NormalAdd(int a, int b)
{
Console.WriteLine((a + b).ToString());
}
public void ExtraAdd(int a, int b)
{
Console.WriteLine((a + b + 5).ToString());
}
public void Excute(int a, int b, AddEventHandler addDelegate)
{
addDelegate(a, b);
}
到此,所以定义均己完成。接下来就Main()里的执行s。
为了给委托绑定DelegateAndEvent内的方法,首先实例化了DelegateAndEvent,注意这行 AddEventHandler addDelegate = de.NormalAdd;该语句完成了两项功能:
首先:实例化AddEventHandler.
其次:给委托绑定了NormalAdd()方法,此时,委托AddEventHandler将与该方法具有完全相同的行为。
运行结果: 8.
使用委托可以将多个方法绑定到同一个委托实例,这称为多路广播。若要向委托的方法列表(调用列表)中添加额外的方法,只需加法赋值运算符( “+=”)添加。
现在我们在Main中的AddEventHandler addDelegate = de.NormalAdd;后再给此委托绑定另一个方法addDelegate += de.ExtraAdd;
static void Main(string[] args)
{
DelegateAndEvent de = new DelegateAndEvent();
// Instantiate the delegate.
AddEventHandler addDelegate = de.NormalAdd;
addDelegate += de.ExtraAdd;
de.Excute(3, 5, addDelegate);
Console.Read();
}
我们再次运行程序结果为:
8
13
由此可见,由委托绑定的两个方法都运行了。
注意:第一次用的“=”,是赋值的语法;第二次,用的是“+=”,是绑定的语法。如果第一次就使用“+=”,将出现“使用了未赋值的局部变量”的编译错误。如果第二次也用”=”,则此委托其实只绑定最后一次绑定的方法。
例如:我们把addDelegate += de.ExtraAdd改成addDelegate = de.ExtraAdd;
static void Main(string[] args)
{
DelegateAndEvent de = new DelegateAndEvent();
// Instantiate the delegate.
AddEventHandler addDelegate = de.NormalAdd;
addDelegate = de.ExtraAdd;
de.Excute(3, 5, addDelegate);
Console.Read();
}
再次运行得到的结果为: 13,因为第二次绑定的同时把第一次给冲掉了,因此只执行了最后一次绑定的方法。
可以将多个方法绑定到委托变量就可以把其中不需要的方法去除掉,方法就是用减法赋值运算符(“-=”).
例如,我们把addDelegate += de.ExtraAdd;改成addDelegate -= de.ExtraAdd;
static void Main(string[] args)
{
DelegateAndEvent de = new DelegateAndEvent();
// Instantiate the delegate.
AddEventHandler addDelegate = de.NormalAdd;
addDelegate -= de.ExtraAdd;
de.Excute(3, 5, addDelegate);
Console.Read();
}
运行,得到的结果为:
8