C#里的委托和事件实现Observer

** 一、委托的简介 ** ** **

1 、委托的声明:

  1<access modifier=""> delegate  <returntype> Handler  Name ([parameters]) 
  2
  3例如: 
  4
  5public  delegate  void  PrintHandler(  string  str); 
  6
  7委托声明定义了一种类型,它用一组特定的参数以及返回类型来封装方法。对于静态方法,委托对象封装要调用的方法。对于实例方法,委托对象同时封装一个实例和该实例上的一个方法。如果您有一个委托对象和一组适当的参数,则可以用这些参数调用该委托。 
  8
  92  、委托的使用: 
 10
 11using  System; 
 12
 13public  class  MyClass 
 14
 15{ 
 16
 17public  static  void  Main() 
 18
 19{ 
 20
 21PrintStr myPrinter =  new  PrintStr(); 
 22
 23PrintHandler myHandler =  null  ; 
 24
 25myHandler +=  new  PrintHandler(myPrinter.CallPrint);  //  将委托链接到方法,来实例化委托 
 26
 27if  (myHandler!=  null  ) 
 28
 29myHandler("Hello World!");  //  调用委托,相当于匿名调用委托所链接的方法 
 30
 31Console.Read(); 
 32
 33} 
 34
 35} 
 36
 37public  delegate  void  PrintHandler(  string  str);  //  声明委托类型 
 38
 39public  class  PrintStr 
 40
 41{ 
 42
 43public  void  CallPrint(  string  input) 
 44
 45{ 
 46
 47Console.WriteLine(input); 
 48
 49} 
 50
 51}   
 52  
 53---  
 54  
 55在  C#  中使用委托方法: 
 56
 57·  创建委托所使用的方法必须和委托声明相一致(参数列表、返回值都一致) 
 58
 59·  利用  +=  、  -=  来进行委托的链接  、取消链接  或直接使用  Delegate.Combine  和  Delegate.Remove  方法来实现 
 60
 61·  可以使用  MulticastDelegate  的实例方法  GetInvocationList()  来获取委托链中所有的委托 
 62
 63·  不能撰写包含  out  参数的委托 
 64
 65** 二、  ** ** 事件的简介  ** ** **
 66
 67C#  中的“事件”是当对象发生某些事情时,类向该类的客户提供通知的一种方法。 
 68
 691  、事件的声明: 
 70
 71声明的格式为:  <access modifier=""> event  &lt; delegate type  &gt; EventName 
 72
 73因为使用委托来声明事件,所以在类里声明事件时,首先必须先声明该事件的委托类型  &lt; delegate type  &gt; (如果尚未声明的话)。在上面我们已经提到过了委托类型的声明,但是在  .net  framework  下为事件使用的委托类型进行声明时有  更严格的规定  : 
 74
 75(  1  )、  事件的委托类型应采用两个参数; 
 76
 77(  2  )、两个参数分别是:指示事件源的“对象源”参数和封装事件的其他任何相关信息的“  e  ”参数; 
 78
 79(  3  )、“  e  ”参数的类型应为  EventArgs  类或派生自  EventArgs  类。 
 80
 81如下的定义: 
 82
 83public  delegate  void  PrintHandler(  object  sender,System.EventArgs e); 
 84
 85然后我们才能声明  该委托类型  的事件 
 86
 87例如: 
 88
 89public  event  PrintHandler  Print  ; 
 90
 91当事件发生时,将调用其客户提供给它的委托。 
 92
 932  、调用事件: 
 94
 95类声明了事件以后,可以就像处理所指示的委托类型的字段那样处理该事件。如果没有任何客户将委托与该事件绑定,则该字段将为空;否则该字段引用应在调用该事件时调用的委托。因此,调用事件时通常先检查是否为空,然后再调用事件。(调用事件,即触发事件,只能从声明该事件的类内进行) 
 96
 97if  (  Print  !=  null  ) 
 98
 99{ 
100
101Print  (  this  ,e); 
102
103} 
104
1053、事件绑定: 
106
107从类的外面来看,事件就象类的一个公共成员,通过  类名  ** .  ** 事件名  的形式来访问,但是只能对它做绑定和解除绑定的操作,而不能有其他操作。 
108
109类名  .  Print  +=  new  PrintHandler(  绑定的方法名  )  //  将某个方法绑定到  Print  事件上 
110
111类名  .  Print  -=  new  PrintHandler(  绑定的方法名  )  //  将某个已绑定到  Print  事件上的方法从  Print  事件上解除 
112
113** **
114
115** 三、委托和事件的使用  ** ** **
116
117委托和事件在用户界面程序里用的比较的多,比如象在  winform  或  webform  的用户  UI  上的  button  和它的  click  事件: 
118
119//  将  Button1_Click()  方法绑定到按钮控件  Button1  的  Click  事件上 
120
121this  .  Button1  .Click +=  new  System.EventHandler(  this  .  Button1  _Click); 
122
123private  void  Button1_Click(  object  sender, System.EventArgs e)  //  Button1_Click()  方法 
124
125{ 
126
127…… 
128
129} 
130
131然而除了用户界面程序外,在很多其他地方也用到了事件驱动模式,比如观察者模式(  Observer  )或发布  /  订阅(  Publish/Subscribe  )里:在一个类里发布(  Publish  )某个可以被触发的事件,而其他的类就可以来订阅(  Subscribe  )该事件。一旦这个发布者类触发了该事件,那么运行时环境会立刻告知所有订阅了该事件的订阅者类:这个事件发生了!从而各个订阅者类可以作出它们自己的反应(调用相应方法)。 
132
133我们来举一个生活中的实际例子来说明如何使用委托和事件,以及使用委托和事件所带来的好处: 
134
135比如说有一个公司(场景),你是老板,手下有  主管  和  员工  ,作为老板你会指派(委托)  主管  管理  员工  的工作,如果某个  员工  玩游戏,则让某个  主管  从该  员工  的薪水里扣去  500  元钱。    
136  
137这就是现实中的委托。    
138  
139而在写程序中,假设程序员就是老板,有两个类分别为  主管  和  员工  ,而  主管小王  和  员工小张  就是两个类的对象实例。  员工类  有  一个方法:玩游戏,同时就有一个玩游戏的事件,他一玩游戏就会激发这个事件。而  主管类  就是负责处理该事件的,他负责把玩游戏的  员工  的  薪水  扣除  500  。 
140
141** (一)、  ** 首先,我们来看看在 **非委托** 的情况下比较常见的一种设计方式(当然这不是唯一的方式,也不是最好的方式,但是很常见): 
142
143using  System; 
144
145namespace  CSharpConsole 
146
147{ 
148
149public  class  场景 
150
151{ 
152
153[STAThread] 
154
155public  static  void  Main(  string  [] args) 
156
157{ 
158
159Console.WriteLine("场景开始了."); 
160
161// 生成主管类的对象实例 小王 
162
163&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt   
164---</access></returntype></access>
Published At
Categories with Web编程
Tagged with
comments powered by Disqus