1、语法基础
将函数作为参数传递在C及C++中是用函数指针,在Lisp中函数本来就是参数的一种,而在C#中则用到的是委托——Delegate。委托实际上是一种引用类型(引用程序中以后会被调用的一个或一组方法,派生自System.MulticastDelegate),跟类(class)、接口(interface)等是类似的。
定义一个委托的例子:
public delegate double CalMath(double num1,double num2);
其中的访问修饰符public根据需要也可以是private、internal、protect等;返回类型double也可以是其他任何返回类型,包括void(此时往往定义的是一个组播委托,后面将会介绍);参数与函数参数并无差别,只是参数名num1、num2是任意的,不会用到实现中。
定义一个委托后,使用它前可先将其实例化(当然,也不一定非要实例化),例如
CalMath func1 = new CalMath(AnyFunction);
注意这里的实参AnyFunction是我们实现委托时用到的函数,它必须接受两个double类型的参数,并返回一个double类型的值,这与委托定义相一致。例如:
public static double AnyFunction(double n1,double n2)
{
returnn1*n2;
}
此时,AnyFunction返回参数之积。
那么在使用委托时我们可以使用这样的语法:
func1(0.5, 2) //将返回值1
2、组播委托
组播委托的概念是指一组委托(或一个委托数组),组播委托的返回值必须是void,否则系统将不知从一组委托中的哪一个返回值。其定义方法与委托一致,例如
public delegate void CalMath(double num1,double num2);
下面假设有这么三个函数
public static void MulFunction(double n1,double n2)
{
Console.WriteLine("Here do Multiply, and the result is: " + n1* n2);
}
public static void AddFunction(double n1,double n2)
{
Console.WriteLine("Here do Add, and the result is: " + (n1 +n2));
}
public static void DivFunction(double n1,double n2)
{
Console.WriteLine("Heredo Divide, and the result is: " + n1 / n2);
}
分别执行两个数的乘法、加法和除法操作。
下面介绍如何使用组播委托:
CalMath funcs = new CalMath(MulFunction);
funcs += new CalMath(AddFunction);
funcs += new CalMath(DivFunction);
通过上述三个语句就将三个操作同时添加到了一个组播委托中,如果执行它:
funcs(2, 5);
则结果将会显示:
Here do Multiply, and the result is: 10
Here do Add, and the result is: 7
Here do Divide, and the result is: 0.4
注意+=符号若换成-=则表示将某函数从组播委托中移除。如:
funcs -= new CalMath(AddFunction); //将加法运算从funcs中移除
委托的用途很广泛,当在编译时不清楚某个函数具体如何执行时可以使用委托。委托与其搭档——事件(event)的默契配合几乎构成了GUI编程的基础。另外,委托与Lambda方法的关系也是很紧密的。