这几天在研究委托与事件,中间陆陆续续的穿插了很多事情,学习也就一直断断续续,昨晚总算把事件也看了。
下面是我的一些个人看法,有不对的地方还请各位批评指正:)
委托适用场合:当类可能需要某一方法的多个实现时(可参考MSDN);使用事件时;多线程;需要封装静态方法时;需要组合方法时(封装逻辑)。
委托使得可以将方法当作另一个方法的参数来进行传递,这种将方法动态地赋给参数的做法,可以避免在程序中大量使用If-Else(Switch)语句,同时使得程序具有更好的可扩展性。在使用时必须先声明,初始化时必须传递一个与其注册时一致的方法名(即参数个数、类型,返回值类型必须一致),否则会出现“方法没有采用“0”个参数的重载”编译错误。
该说明参见http://www.tracefact.net/CSharp-Programming/Delegates-and-Events-in-CSharp.aspx
【委托是一个定义签名的类型,即方法的返回值类型和参数列表类型。可以使用委托类型来声明一个变量,该变量可以引用与委托签名相同的所有方法。】
在VS05里可以不用初始化即自动匹配和它签名相同的方法。而03里必须严格初始化并进行方法添加。
范例demo[Delegate]
Code
1Code
2using System;
3using System.Collections.Generic;
4using System.Text;
5
6namespace demo_Delegate_
7{
8 public delegate void D(double a, double b); //委托定义
9
10 /**//// <summary>
11 /// 比较类
12 /// </summary>
13 class Complete
14 {
15 private D m_D; //定义一个委托
16
17 /**//// <summary>
18 /// 比较两个数,输出其最大值
19 /// </summary>
20 /// <param name="num1">比较数num1</param>
21 /// <param name="num2">比较数num2</param>
22 /// <returns></returns>
23 public void max(double num1, double num2)
24 {
25 double maxnum;
26 if (num1 > num2)
27 {
28 maxnum = num1;
29 }
30 else
31 {
32 maxnum = num2;
33 }
34 Console.WriteLine("两数最大值是 " + maxnum);
35 }
36
37 /**//// <summary>
38 /// 比较两个数,输出其最小值
39 /// </summary>
40 /// <param name="num1">比较数num1</param>
41 /// <param name="num2">比较数num2</param>
42 /// <returns></returns>
43 public void min(double num1, double num2)
44 {
45 double minnum;
46 if (num1 < num2)
47 {
48 minnum = num1;
49 }
50 else
51 {
52 minnum = num2;
53 }
54 Console.WriteLine("两数最小值是 " + minnum);
55 }
56
57 /**//// <summary>
58 /// 调用某种比较方法后的结果值
59 /// </summary>
60 /// <param name="num">一个只包含两个数据的一维数组</param>
61 /// <param name="d">委托类型D</param>
62 public void print(double[] num, D d)
63 {
64 d(num[0], num[1]);
65 }
66
67 public void print(double[] num)
68 {
69 m_D = new D(min);
70 m_D += max;
71 print(num,m_D);
72 }
73
74 /**//// <summary>
75 /// 输出数组的原值
76 /// </summary>
77 /// <param name="num">一维数组</param>
78 public void Print(double[] num)
79 {
80 string context = "";
81 for (int i = 0; i < num.Length; i++)
82 {
83 context += num[i].ToString() + " ";
84 }
85 Console.WriteLine("原数组为 " + context);
86 }
87 }
88
89 class Program
90 {
91 static void Main(string[] args)
92 {
93 Complete com = new Complete();
94 //D d1 = new D(com.min);
95 //d1 += com.max;
96 //d1 += com.min;
97 double[] a ={ 2.789, 4.4317 };
98 com.Print(a);
99 com.print(a);
100 //com.print(a, d1);
101 Console.ReadLine();
102 }
103 }
104}
105
事件适用场合:当多方对同一个委托变量进行操作时;需要响应某种操作并需自行进行处理时;
事件是委托的变量(实例)。事件在委托实例上加了一层保护,保护客户的委托以免被重新设置及委托调用链被清空,只允许对委托调用链进行添加或移除操作。
范例:demo[EventConsole]
Code
1using System;
2using System.Collections.Generic;
3using System.Text;
4
5namespace demo_EventConsole_
6{
7 public delegate void mydelegate(string str);//委托定义
8
9 /**//// <summary>
10 /// 触发事件类
11 /// </summary>
12 class myevent
13 {
14 public event mydelegate myeventhandle;//事件定义
15
16 public void TouchEvent()
17 {
18 while (true)
19 {
20 string str = Console.ReadLine();
21 if (str.ToLower() == "exit")//若输入不是exit则触发事件
22 {
23 Console.WriteLine("Input is exit command(exit),See you later,Bye");
24 break;
25 }
26 OnTouchEvent(str);
27 }
28
29 }
30
31 protected virtual void OnTouchEvent(string str)//可以从继承的子类中调用并更改我的实现,这是个好处,使得我可以在事件触发之前做一些附加工作^_^
32 {
33 if (str.Trim() != "")
34 {
35 Console.WriteLine("触发事件如下:");
36 myeventhandle(str);
37 }
38 else
39 {
40 Console.WriteLine("输入为空(- -!)");
41 }
42 }
43 }
44
45 /**//// <summary>
46 /// 事件处理类
47 /// </summary>
48 class myeventhandle
49 {
50 public void PrintLower(string str)
51 {
52 Console.WriteLine(str + " 转换为小写后输出:" + str.ToLower());
53 }
54
55 public void PrintUpper(string str)
56 {
57 Console.WriteLine(str + " 转换为小写后输出:" + str.ToUpper());
58 }
59
60 }
61
62 class Program
63 {
64 static void Main(string[] args)
65 {
66 myevent mye = new myevent();
67 myeventhandle myh = new myeventhandle();
68 mye.myeventhandle += new mydelegate(myh.PrintLower);
69 mye.TouchEvent();
70 Console.ReadLine();
71 }
72 }
73}
还请各位批评指正,相互学习
委托与事件延伸http://www.codeproject.com/KB/cs/events.aspx