这几天在研究委托与事件,中间陆陆续续的穿插了很多事情,学习也就一直断断续续,昨晚总算把事件也看了。
下面是我的一些个人看法,有不对的地方还请各位批评指正:)
委托适用场合:当类可能需要某一方法的多个实现时(可参考MSDN);使用事件时;多线程;需要封装静态方法时;需要组合方法时(封装逻辑)。
委托使得可以将方法当作另一个方法的参数来进行传递,这种将方法动态地赋给参数的做法,可以避免在程序中大量使用If-Else(Switch)语句,同时使得程序具有更好的可扩展性。在使用时必须先声明,初始化时必须传递一个与其注册时一致的方法名(即参数个数、类型,返回值类型必须一致),否则会出现“方法没有采用“0”个参数的重载”编译错误。
该说明参见http://www.tracefact.net/CSharp-Programming/Delegates-and-Events-in-CSharp.aspx
【委托是一个定义签名的类型,即方法的返回值类型和参数列表类型。可以使用委托类型来声明一个变量,该变量可以引用与委托签名相同的所有方法。】
在VS05里可以不用初始化即自动匹配和它签名相同的方法。而03里必须严格初始化并进行方法添加。
范例demo[Delegate]

Code
1
Code
2
using System;
3
using System.Collections.Generic;
4
using System.Text;
5
6
namespace 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
1
using System;
2
using System.Collections.Generic;
3
using System.Text;
4
5
namespace 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