.NETFramework 2.0中提供了Delegate类,表示委托。委托是一种数据结构,是指向一个方法的指针,是一种安全的封装方法类型。
委托是一种数据类型(的实例),这种类型引用一个方法,一旦为一个委托分配(可以理解为“挂接”)上一个方法,那么它的行为将与这个方法一致,委托可以像任何方法一样使用,如参数及返回值等。
代理是一个可以引用方法的对象。创建一个代理也就创建了一个引用方法的对象,进而通过此引用就可以调用那个方法。因此,代理可以调用它所指向的方法。尽管方法不是对象,但它在内存中也有物理地址,此地址就是方法的入口点,也就是方法被调用的地址。方法的地址可以赋给代理。
一旦一个代理引用了一个方法,就可以通过此代理来调用所有引用的方法,而且代理引用的方法是可以改变的,这样同一个代理就可以调用多个不同的方法。代理的主要优势就是允许指定调用方法,方法不是在编译时确定的,而是在运行时才决定的。
委托类型声明的格式如下:
publicdelegate void TestDelegate(string message);
delegate关键字用于声明一个引用类型,该引用类型可用于封装命名方法或匿名方法;TestDelegate指定代理名称,可以进行自定义命名。(string message)代表了para meter-list用来指定代理调用的方法所需的参数列表。委托声明中的参数列表极其重要,与返回类型共同制约着代理的成功与否。只有在代理中两者都满足了委托声明的一致性,代理才能生效。
一旦声明了代理,此代理就只能调用代理指定的与返回值类型和参数相吻合的方法。使用代理时,最重要的一点就是代理只能调用和其特征相吻合的方法。这使得代理可以在运行时决定调用哪个方法。而且代理不但可以调用对象的实例化方法,还可以调用类的静态方法。所有的问题都归结于方法的特征要与代理相吻合。
下面是一些需要注意的事项:
(1)在C#中,所有的代理都是从System.Delegate类派生的(delegate是System.Delegate的别名)。
(2)代理隐含具有sealed属性,即不能用来派生新的类型。
(3)代理最大的作用就是为类的事件绑定事件处理程序。
(4)在通过代理调用函数前,必须先检查代理是否为空(null)。若非空,才能调用函数。
(5)在代理实例中可以封装静态的方法,也可以封装实例方法。(www.xing528.com)
(6)在创建代理实例时,需要传递将要映射的方法或其他代理实例以指明代理将要封装的函数原型(.NET中称为方法签名:signature)。如果映射的是静态方法,传递的参数应该是类名.方法名;如果映射的是实例方法,传递的参数应该是实例名.方法名。
(7)只有当两个代理实例所映射的方法以及该方法所属的对象都相同时,才认为它们是相等的(从函数地址考虑)。
(8)多个代理实例可以形成一个代理链,System.Delegate中定义了用来维护代理链的静态方法Combion、Remove,分别向代理链中添加代理实例和删除代理实例。
(9)代理的定义必须放在任何类的外面,如delegateintMyDelegate();而在类的方法中调用MyDelegated=newMyDelegate(MyClass.MyMethod)来实例化自定义代理的实例。
(10)代理三部曲:
1)自定义代理类:delegate 0t yDelegate()。
2)实例化代理类:MyDelegated=newMyDelegate(MyClass.MyMethod)。
3)通过实例对象调用方法:intret=d()。
下面的示例代码体现了委托代理中的几个关键点:代理一个静态的方法和匿名方法,同时也可以代理封装命名方法。
程序分析:本例程序声明了一个称为SampleDelegate的代理,带有一个string型的参数,没有返回值。
在类Program中声明了两个静态方法和一个匿名方法,每个静态方法都有一个匹配特征,对传进来的字符串进行了不同的处理。同样匿名方法也实现了字符串的处理作用。
在静态方法SampleDelegateMethod()中实现了对传入字符串的原本输出,以作为下面实例的比较;在SampleDelegateMethod1()方法中实现了对传入字符串的添加字符输出,将传出的字符串后面拼接上123;在匿名方法SampleDelegateMethod1()中实现了字符串拼接的不同性,实现了不同的字符串处理方法。
同时Test1定义了一个类,其中定义了一个strConvert方法,其基本的属性与委托的声明保持一致,含有一个字符串的参数,无返回值。SampleDelegated4=newSampleDelegate(test1.strConvert)实现了实例化方法的代理,这样就可以通过代理d4的实例方法来操纵字符串。当实例化代理时,只指定想要引用的代理的方法名(注意:不加后面的“()”),同时所引用方法的特征与代理的声明相匹配,否则会导致编译错误。
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。