C#中使用委托

C#中使用委托

在C#中可以将委托看作一种新的类型,它是用来定义需要用来传递的方法的签名。类似于C++中的函数指针,它定义函数的输入参数和输出参数,是一批相似方法的代名词。但是为了种种原因,例如代码安全。所以 .Net Framework 在语法上不允许直接传递方法或叫函数,如果确实要这么处理,那就需要将方法包装成为一个新类型(委托)对象中。委托是一种特殊的对象,其他的对象包含的是数据和方法。但委托包含的是方法的细节。

我们通常习惯于向一个方法传递数值或对象,但是有时我们也希望向这个方法传递另一个方法,但这个方法的名称在设计时却是不确定的,只有到了运行时才能确定。这时就可以把要传递的方法用委托来定义,在使用时要把他看作是一个方法的代名词。


使用委托的步骤:
1、声明委托,定义参数列表和返回类型。
2、实例化委托,同时将一个符合委托声明参数的方法名称传递给委托。
3、调用委托,简单来说就象使用方法一样来使用委托的实例。

如下例:

 1 using System;
 2 using System.Collections;
 3 
 4 namespace Exam
 5 {
 6     // 自定义类
 7     public class Class1
 8     {
 9         private string name;
10         public string Name
11         {
12             set { name = value; }
13             get { return name; }
14         }
15     }
16 
17     // 声明一个委托用来代表所有输入参数是Class1,输出参数是string的方法。
18     public delegate string Delegate(Class1 cls);
19 
20     class Class2
21     {
22         [STAThread]
23         static void Main(string[] args)
24         {
25             // 实例化委托,同时指定这个委托实例所代表的方法名就是这个类
26             // 的一个静态方法getName,注意这里不需要指定方法的参数。
27             Delegate test = new Delegate(getName);
28 
29             Class1 c1 = new Class1();
30             c1.Name = "Class1";
31 
32             // 调用委托test所代表的方法,同时传递他需要的参数c1。
33             Console.WriteLine(test(c1));
34 
35             Console.ReadKey();
36         }
37 
38         static string getName(Class1 cls)
39         {
40             return cls.Name;
41         }
42     }
43 }
44 

最后,委托的实例可以表示任何类型的任何对象上的实例方法或静态方法,只要方法签名和委托签名相同即可。


多播委托

上面使用的委托只包含了一个方法,调用委托时执行方法的次数也只有一次。其实,如果一个委托它的返回值是 void 那么编译器就自动把它当作一个多播委托来处理。什么意思呢?也就是可以使用 += 方法向这个委托的实例添加其他方法。那么在使用这个实例时就会执行它所代表的所有方法。

例如:
 1 using System;
 2 using System.Collections;
 3 
 4 namespace Exam
 5 {
 6     // 无返回值的委托是多播委托
 7     public delegate void CountMethodDelegate(int a, int b);
 8 
 9     class Class1
10     {
11 
12         // 加法
13         static void Plus(int a, int b)
14         {
15             Console.WriteLine(String.Format("A:{0} + B:{1} = {2}",a,b,a+b));
16         }
17 
18         // 减法
19         static void Minus(int a, int b)
20         {
21             Console.WriteLine(String.Format("A:{0} - B:{1} = {2}", a, b, a - b));
22         }
23 
24         // 乘法
25         static void Multiply(int a, int b)
26         {
27             Console.WriteLine(String.Format("A:{0} * B:{1} = {2}", a, b, a * b));
28         }
29         
30         // 除法
31         static void Divide(int a, int b)
32         {
33             Console.WriteLine(String.Format("A:{0} / B:{1} = {2}", a, b, a / b));
34         }
35 
36         [STAThread]
37         static void Main(string[] args)
38         {
39             int A, B;
40             A = 100;
41             B = 7;
42 
43             // 连续向这个委托的实例添加方法。
44             CountMethodDelegate test = new CountMethodDelegate(Plus);
45             test += new CountMethodDelegate(Minus);
46             test += new CountMethodDelegate(Multiply);
47             test += new CountMethodDelegate(Divide);
48 
49 
50             // 调用委托test所代表的方法,同时传递他需要的参数A和B。
51             // 一次调用,执行所有方法。
52             test(A, B);
53 
54             Console.ReadKey();
55         }
56     }
57 }
58 

多播委托是一个派生于 System.MulticastDelegate 的类,它派生于基类 System.Delegate。它的其他成员允许把多个方法调用链接在一起,成为一个列表。但这并不代表执行这些方法的顺序会按照添加时的顺序执行,要避免编写依赖特定顺序调用方法的代码。

洪虎

2006-10-2 更新
原文地址:https://www.cnblogs.com/eric1394/p/520242.html