我是对Java了解相对较多,而对C#则是因工作需要才去看了一下,C#跟Java在语法上非常相似,而最初让我比较困惑的就是委托、事件部分,相信大多数初学者也有类似的困惑。经过跟Java的对比学习,发现这其实跟Java的监听、事件是等同的,只是表述上不同罢了。
      委托+事件是观察者模式的一个典型例子,所谓的委托其实就是观察者,它会关心某种事件,一旦这种事件被触发,这个观察者就会行动。
      下面是最近写的一个例子,相信能够加深大家对委托和事件的理解。

    1. using System;
    2. using System.Collections.Generic;
    3. using System.Text;
    4. namespace ConsoleApplication1
    5. {
    6. //声明一个委托
    7. public delegate void TimeEventHandler(object obj, TimeEventArgs args);
    8. class Program
    9. {
    10. static void Main(string[] args)
    11. {
    12. Clock clock = new Clock(); //实例化一个时钟
    13. MyClassEventHandler tehc = new MyClassEventHandler(); //实例化一个观察者类
    14. //将事件跟我们定义的观察者进行连接
    15. //这样,clock就会知道,每当TimeChanged事件被触发,就会去通知这个观察者
    16. //注意我们连接的时候使用的并不是直接的观察者类实例中的ShowTime()方法
    17. //而是一个委托,并在这个委托中传递ShowTime()方法,这也是"委托"的真正意义所在:
    18. //我有一个方法,但我委托你来帮我关联到事件,因为事件只会直接跟委托打交道,
    19. //而不是观察者的具体某个方法
    20. clock.TimeChanged += new TimeEventHandler(tehc.ShowTime);
    21. clock.go();
    22. }
    23. }
    24. //TimeEventArgs是我们自己定义的一个类,用于保存事件中的参数.这里我们分别保存时间的时分秒
    25. public class TimeEventArgs:EventArgs
    26. {
    27. private int hour;
    28. private int minute;
    29. private int second;
    30. public TimeEventArgs(int hour,int minute,int second)
    31. {
    32. this.hour = hour;
    33. this.minute = minute;
    34. this.second = second;
    35. }
    36. public int Hour{
    37. get {
    38. return this.hour;
    39. }
    40. }
    41. public int Minute {
    42. get {
    43. return this.minute;
    44. }
    45. }
    46. public int Second {
    47. get {
    48. return this.second;
    49. }
    50. }
    51. }
    52. //观察者类,它有一个符合我们上面定义的"委托"的方法
    53. //也就是void ShowTime(object obj,TimeEventArgs args)
    54. //从这个方法的定义可以看到,我们只会关心返回类型和方法的参数,而方法名称则无所谓
    55. class MyClassEventHandler
    56. {
    57. public void ShowTime(object obj,TimeEventArgs args)
    58. {
    59. Console.WriteLine("现在时间:"+args.Hour+":" + args.Minute + ":" + args.Second);
    60. }
    61. }
    62. //时钟类
    63. class Clock
    64. {
    65. //我们在这个类中定义了一个"TimeChanged"事件,注意其前面有两个关键字"event"和"TimeEventHandler"
    66. //其中event表示这是一个事件,而不是方法或属性,TimeEventHandler则指出,谁要监听TimeChanged事件,它就必须有一个符合TimeEventHandler(委托)的方法
    67. public event TimeEventHandler TimeChanged;
    68. public Clock()
    69. {
    70. //注意,这里的null的含义是指TimeChanged事件当前还没有观察者关注它
    71. //如果某个观察者要关注TimeChanged事件,它必须要让这个事件知道,方法是使用操作符"+="来借助委托将其加载到事件上
    72. TimeChanged = null;
    73. }
    74. //时钟开始走动,我们的目标是每秒钟触发一次TimeChanged事件
    75. public void go()
    76. {
    77. DateTime initi = DateTime.Now;
    78. int h1 = initi.Hour;
    79. int m1 = initi.Minute;
    80. int s1 = initi.Second;
    81. while (true)
    82. {
    83. DateTime now = DateTime.Now;
    84. int h2 = now.Hour;
    85. int m2 = now.Minute;
    86. int s2 = now.Second;
    87. if (s2 != s1)
    88. {
    89. h1 = h2;
    90. m1 = m2;
    91. s1 = s2;
    92. //首先建立一个TimeEventArgs对象来保存相关参数,这里是时分秒
    93. TimeEventArgs args = new TimeEventArgs(h2, m2, s2);
    94. //注意这种写法,这一句是用来触发事件,事件不是类,所以不用使用"new"关键字,而且我们看到,这里TimeChanged的两个参数跟我们的委托(TimeEventHandler)是一致的
    95. //其中第一个参数是触发这个事件的对象,我们这里使用的是一个时钟实例(this)
    96. TimeChanged(this, args);
    97. }
    98. }
    99. }
    100. }
    101. }

    C#委托和事件例析 - 图1
    转载自:http://ruizhinet.blog.163.com/blog/static/99213828200901110564999/