委托是寻址方法的.NET版本。委托是类型安全的类,它定义了返回类型和参数的类型。委托是对方法的引用,也可以对多个方法进行引用,委托可以理解为指向方法地址的指针。
如:delegate int ReturnIntHandler(int a,int b);//int是返回类型,a和b是引用类型,这是委托执行的方法必须满足如下格式:int method(int param1,int param2);
二、委托
当要把方法传递给其它方法时,需要使用委托。委托是一种特殊类型的对象,其特殊之处在于,我们以前定义的所有对象都包含数据,而委托包含的只是一个或多个方法的地址。
1、声明委托
委托使用关键字 delegate 进行定义。
定义委托基本上就是定义一个新类,所以可以在定义类的任何相同地方定义委托。可以在委托定义上应用常见的访问修饰符:public、private、protected等。其访问作用域也雷同于类。
2、使用委托
为了减少输入量,只需要委托实例,就可以只传递地址的名称。这称为委托推断。
delegate int CalculateMethodInvoker(int x, int y); class Program { static void Main(string[] args) { CalculateMethodInvoker calculateMethodInvoker = CalculateHelper.Sum; int x = 100, y = 200; Console.WriteLine("x,y相加:{0}", Calculate(calculateMethodInvoker, x, y)); calculateMethodInvoker = CalculateHelper.Multiply; Console.WriteLine("x,y相乘:{0}", Calculate(calculateMethodInvoker, x, y)); Console.ReadKey(); } public static int Calculate(CalculateMethodInvoker calculateMethodInvoker, int x, int y) { //return calculateMethodInvoker(x, y); //return calculateMethodInvoker.Invoke(x, y);//是不是当前线程都可以 IAsyncResult result = calculateMethodInvoker.BeginInvoke(x, y, null, calculateMethodInvoker);//异步,这里只是做展示,EndInvoke类似于async中的await,这里不能实现异步效果 return calculateMethodInvoker.EndInvoke(result); } } public class CalculateHelper { public static int Sum(int x, int y) { return x + y; } public static int Multiply(int x, int y) { return x * y; } }
3、Action<T>和Func<T>委托
除了为每个参数和返回类型定义一个新的委托类型外,还可以使用Action<T>和Func<T>委托。
泛型Action<T>委托表示引用一个void返回类型的方法,没有泛型参数的Action类可调用没有参数的方法,如Action 等价于 delegate void mydelegate; Action<int,int>等价于delegate void mydelegate(int param1,int param2);
泛型Func<T>委托表示引用一个有返回值的方法,泛型的最后一个参数时Func的返回值类型,如Func<int,int,bool>,等价于delegate bool mydelegate(int param1,int param2);
4、多播委托
委托也可以包含多个方法。这种委托成为多播委托。如果调用多播委托,就可以按顺序连续调用多个方法。为此,委托的签名就必须返回void;否则,就只能得到委托调用的最后一个方法的结果。多播委托识别运算符“-”、“+”、“-=”、“+=”以从委托中增加或删除方法调用。
如:
class Program { static void Main(string[] args) { Action<int, int> calFunc = CalculateHelper.Sum; calFunc += CalculateHelper.Multiply;//多播加 int x = 100, y = 200; Calculate(calFunc, x, y); calFunc =calFunc- CalculateHelper.Multiply;//多播减 Calculate(calFunc, x, y); Console.ReadKey(); } public static void Calculate(Action<int, int> calculateMethodInvoker, int x, int y) { Console.WriteLine("运行结果:"); //calculateMethodInvoker(x, y); foreach (Action<int, int> item in calculateMethodInvoker.GetInvocationList())//遍历,这里需要转为为当前类型委托 { try { item(x, y);//执行委托指向方法 } catch (Exception ex) { Console.WriteLine(ex.Message); } } } }