C#中使用委托
C#中使用委托
在C#中可以将委托看作一种新的类型,它是用来定义需要用来传递的方法的签名。类似于C++中的函数指针,它定义函数的输入参数和输出参数,是一批相似方法的代名词。但是为了种种原因,例如代码安全。所以 .Net Framework 在语法上不允许直接传递方法或叫函数,如果确实要这么处理,那就需要将方法包装成为一个新类型(委托)对象中。委托是一种特殊的对象,其他的对象包含的是数据和方法。但委托包含的是方法的细节。
我们通常习惯于向一个方法传递数值或对象,但是有时我们也希望向这个方法传递另一个方法,但这个方法的名称在设计时却是不确定的,只有到了运行时才能确定。这时就可以把要传递的方法用委托来定义,在使用时要把他看作是一个方法的代名词。
使用委托的步骤:
1、声明委托,定义参数列表和返回类型。
2、实例化委托,同时将一个符合委托声明参数的方法名称传递给委托。
3、调用委托,简单来说就象使用方法一样来使用委托的实例。
如下例:
最后,委托的实例可以表示任何类型的任何对象上的实例方法或静态方法,只要方法签名和委托签名相同即可。
多播委托
上面使用的委托只包含了一个方法,调用委托时执行方法的次数也只有一次。其实,如果一个委托它的返回值是 void 那么编译器就自动把它当作一个多播委托来处理。什么意思呢?也就是可以使用 += 方法向这个委托的实例添加其他方法。那么在使用这个实例时就会执行它所代表的所有方法。
例如:
多播委托是一个派生于 System.MulticastDelegate 的类,它派生于基类 System.Delegate。它的其他成员允许把多个方法调用链接在一起,成为一个列表。但这并不代表执行这些方法的顺序会按照添加时的顺序执行,要避免编写依赖特定顺序调用方法的代码。
洪虎
2006-10-2 更新
在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
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
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 更新