1.定义:委托(Delegate)相当于函数指针,指向某一个具体的方法。是一种引用类型,需要像类和对象一样申明和实例化。
2.用处:委托实现对方法的动态调用,实现事件机制。
补充:c++函数指针(有了函数指针后可以定义函数类型的参数并传递函数作为参数):
函数有地址,函数的地址是存储其机器语言代码的内存的开始地址。函数地址是函数名。将函数作为参数进行传递也是传递函数名。
函数原型:
double Killer(int);
对应的指向Killer函数的指针:
double (*kl)(int);//kl为函数指针名,指向函数的指针,值为函数的地址
(注意:double *kl(int);//定义返回值为指针类型(double *)的函数名为kl的函数)
将函数名赋给函数指针:
kl=Killer;
在函数地址赋给函数指针成功以后,我们就可以用函数指针调用函数了。
#include
using namespace std;
double betsy(int);
double pam(int);
void estimate(int lines,double (*pf)(int));
int main(){
int code;
cout<<“How many lines of code do you need? “;
cin>>code;
cout<<“Here’s Betsy’s estimate:\n”;
estimate(code,betsy);
cout<<“Here’s pam’s estimate:\n”;
estimate(code,pam);
return 0;
}
double betsy(int lns){
return 0.05lns;
}
double pam(int lns){
return 0.03lns+0.004lnslns;
}
void estimate(int lines,double (*pf)(int)){
cout<<lines<<” lines will take “;
cout<<(*pf)(lines)<<” hours”<<endl;
}
3.委托的规范用法
委托可以看成c#里的函数指针,但c#中的函数(方法)都是在类中定义的,没有单独的方法。可以在类中定义委托(委托可以看成类),实例化委托时将类的方法名赋给委托的实例,且类方法的原型要与委托的类型一致。
如:
using System;
class MathOperations
{
public static double MultiplyByTwo(double value)
{
return value * 2;
}
public static double Square(double value)
{
return value * value;
}
}
namespace Demo
{
//定义委托
delegate double DoubleOp(double x);//与MathOperations类中的MultiplyByTwo和Square方法一致(参数是一个double类型,返回值为double)
class Program
{
static void Main()
{
//实例化一个委托数组,该数组的每个元素都初始化为由MathOperations类实现的不同操作
DoubleOp[] operations =
{
MathOperations.MultiplyByTwo,
MathOperations.Square
};//等价于operation[0]= MathOperations.MultiplyByTwo;operation[1]=MathOperations.Square;
//遍历委托数组,调用不同的方法
for(int i = 0; i<operations.Length; i++)
{
Console.WriteLine(“Using operations[{0}]:”,i);
ProcessAndDisplayNumber(operations[i],2.0);
ProcessAndDisplayNumber(operations[i],7.94);
ProcessAndDisplayNumber(operations[i],1.414);
Console.WriteLine();
}
}
static void ProcessAndDisplayNumber(DoubleOp action,double value)
{
// 实际上是调用action委托实例 封装的方法,其返回结果存储在result中。
double result = action(value);
Console.WriteLine("Value is {0},result of operation is {1}",value,result);
}
}
}
注意:创建委托实例时根据方法是否为static类型采用不同形式
Func d1 = new Func(对象名.方法名); //非静态方法
Func d2 = new Func(类名.方法名); //静态方法
简写为:Func d1 = 对象名.方法名; Func d2=类名.方法名;
4.泛型委托
Action和Func(c#内置的两个委托)
Action: 返回值为void的委托
有16个重载Action,Action,Action<T,T>…
Func: 返回值不为void的委托
Func,Func<T,T>…, 最后一个泛型型参数是返回值类型。
5.多播委托(无返回值,可以将委托看成List,使用+=,-=往里添加或删除委托)
一个委托实例中可以“包含”多个函数
调用委托,就是调用其中多个函数
多个函数间的先后顺序是没有意义的
返回值也就没有太多意义
也可以使用委托泛型:
如上例,调用一个委托的对象执行了多个函数。
6.Array.ForEach()
Array.ForEach(数组名,委托/函数名);//函数功能是把数组中所有的元素依次作为实参传递给委托执行。
例如:
输出结果为:
Method2:Hello
Method2:world
Method2:!