本文共 2524 字,大约阅读时间需要 8 分钟。
委托是安全封装方法的类型,类似于c和c++中的函数指针。与c函数指针不同的是,委托是面向对象的、类型安全的和可靠的。委托类型是由委托的名称确定。以下是声明名为Del的委托,该委托可以封装采用字符串作为参数并返回void的方法:
public delegate void Del(string message);
委托对象通常通过提供委托将封装的方法的名称或使用匿名的方法构造。对委托进行实例化后,委托会将对其进行的方法调用传递到该方法。调用方法传递到为他的参数将传递到该方法,并且委托会将方法的返回值返回到调用方。这被称为调用委托。实例化的委托可以按封装的方法本身进行调用。
//被委托的方法public static void delegateMethod(string message){ System.Console.WriteLine(message);}//委托的构造和调用Del handler = delegateMethod;handler("Hello World");
由于实例化的委托是一个对象,因此可以作为参数传递或者分配给一个属性。这允许方法作为参数接受委托并在稍后调用委托。这被称于异步回调。当使用这种方式使用委托时,使用委托的代码不需要知道使用方法的实现方法。
//使用委托作为参数的方法public void MethodWithCallback(int a, int b, Del callback){ callback("The number is :" + (a + b).ToString());}//调用该方法MethodWithCallback(1, 2, handler);
当委托构造为封装实例方法时,委托将同时引用实例和方法。委托不知道除其所封装方法以外的实例类型,因此委托可以引用任何类型的对象,只要该对象有与委托签名匹配的方法。当委托构造为静态方法时,委托仅引用方法。
委托类型派生自.Net Framework中的Delegate类。委托类型是封装的,他们不能派生出其他类,也不能从Delegate派生出自定义类。
//委托构造方法类public class MethodClass{ public void method1(string s); public void method2(string s)}
//实例方法构造委托MethodClass obj = new MethodClass();Del d1 = obj.method1;Del d2 = obj.method2;
加上之前显示的静态delegateMethod,我们现在已经有3个Del的实例。调用委托时,可以调用多个方法,这成为多播。方法是想委托列表添加其它方法,使用加法运算符或加法赋值运算符(“+”或”+=”)添加委托。例如:
Del allMethodDelegate = d1 + d2;allMethodDelegate += handler;
此时allMethodDelegate调用列表包含3个方法,调用allMethodDelegate时,将顺序调用所有三个方法。如果委托使用引用参数,引用将按相反的顺序传递到所有的方法中,并且一种方法进行的任何更改都将在另一种方法上见到。 当方法引发未在方法内捕获到的异常时,该异常将传递到委托的调用方,并且不会调用调用列表中的后续方法。 如果委托具有返回值和/或输出参数,它将返回上次调用方法的返回值和参数。 若要删除调用列表中的方法,请使用减法运算符或减法赋值运算符(“-”或“-=”)。 例如:
allMethodDelegate -= d1;allMethodDelegate = allMethodDelegate - d2;
多播委托广泛用于事件处理中。 事件源对象将事件通知发送到已注册接收该事件的接收方对象。若要注册一个事件,接收方需要创建用于处理该事件的方法,然后为该方法创建委托并将委托传递到事件源。事件发生时,源调用委托。然后,委托将对接收方调用事件处理方法,从而提供事件数据。给定事件的委托类型由事件源确定。 有关详细信息,请参阅事件(C# 编程指南)。
在编译时比较分配的两个不同类型的委托将导致编译错误。 如果委托实例是静态的 System.Delegate 类型,则允许比较,但在运行时将返回 false。 例如:
delegate void Delegate1();delegate void Delegate2();static void method(Delegate1 d, Delegate2 e, System.Delegate f){ // Compile-time error. //Console.WriteLine(d == e); // OK at compile-time. False if the run-time type of f // is not the same as that of d. System.Console.WriteLine(d == f);}
//声明一个delegatedelegate void Del(string str);//声明一个和Del相同签名的方法static void notify(string name);
委托实例实例的几种构造方式:
//使用new实例化一个DelDel del = new Del(Notify);//直接赋值Del del2 = Notify;//匿名的方式Del del3 = delegate(string name) {Console.WriteLine("Notification received for: {0}", name);};//使用Lambda表达式Del del4 = name => { Console.WriteLine("Notification received for: {0}", name); };
转载地址:http://uqlgb.baihongyu.com/