第11章委托与事件_第1页
第11章委托与事件_第2页
第11章委托与事件_第3页
第11章委托与事件_第4页
第11章委托与事件_第5页
已阅读5页,还剩24页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、第第11章章 委托委托(代表代表)与与 事件事件n11.1 委托委托(代表代表)n11.2 事件事件n11.3 事件访问器事件访问器n总结总结11.1 委托委托 11.1.1 前言前言 11.1.2 定义定义 11.1.3 定义委托对象及实例化定义委托对象及实例化 11.1.4 用例用例 11.1.5 进一步理解委托进一步理解委托 11.1.6 组播组播(多重多重)委托委托返回首页11.1.1 前言前言 什么是委托什么是委托? 函数是一个程序运行的代码段函数是一个程序运行的代码段, 调用该函数调用该函数,相当于执行了这段代码段相当于执行了这段代码段. 有时有时,我们需要实现这样一个功能我们需要

2、实现这样一个功能: 定义一个特殊定义一个特殊”变量变量”,此变量的内容为地址此变量的内容为地址,-指向某个函数的代码段指向某个函数的代码段(首地址首地址); 这样这样,当我们当我们”调用调用”该该”变量变量”时时,程序就跳转到代码段去执行了程序就跳转到代码段去执行了.n 这个特殊这个特殊”变量变量” 就是就是 C,C+中的函数的指针中的函数的指针n 因为一个函数有签名有返回值因为一个函数有签名有返回值,所以在所以在C#中中,我们将此我们将此”变量变量”看成是某个看成是某个”类类”生成的生成的对象对象,这样我们把定义的这个这样我们把定义的这个”类类” 称为称为: 委托委托 (代表代表,代理代理,

3、委派委派) 委托的实质委托的实质n委托实质上一种类型委托实质上一种类型 ,即它的地位处于与类即它的地位处于与类(class),结构结构(struct),枚举枚举(enum)一样一样n委托在定义好之后委托在定义好之后,必須必須”实例化实例化”对象对象”才成使用才成使用.n委托的委托的”对象对象”可以用作可以用作 类类,结构的结构的数据成员数据成员看待看待(“引用类型引用类型”)n委托的委托的”对象对象”当然也可以用作当然也可以用作 方法成员的参数方法成员的参数 看待看待11.1.2 定义定义 delegate 返回类型返回类型 委托名委托名(形参形参1,);例例1: delegate void

4、Run();/定义了一个叫定义了一个叫Run的委托的委托 /Get实例化后的可以代表实例化后的可以代表 所有无参数所有无参数,无返回值那一类的函数无返回值那一类的函数 /如如 void Main() void Fun(). 例例2: delegate int Handle(string str); /定义了一个叫定义了一个叫Handle的委托的委托 /它可以指向它可以指向 int Fun(string str); / int Fun1(string str); / 11.1.3 定义委托对象及实例化定义委托对象及实例化 委托名委托名 对象名对象名; 对象名对象名=全名全名.方法名方法名; 委托

5、名委托名 对象名对象名 =new 委托名委托名(初始化参数初始化参数); 例例1: public static void Main() Run main; /定义一个定义一个Get类型的变量类型的变量main main=Main; / main将将 void Main() 的代码段指向的代码段指向 / Run main=new Run(Main); /实例化实例化main main(); /执行执行Main代码段代码段,此例将形成死循环此例将形成死循环 注意注意: 1.委托仅仅是一个类型委托仅仅是一个类型,故一定要定义一个变量才能使用故一定要定义一个变量才能使用 2. 变量在初始时变量在初始时

6、,只需将只需将”方法名方法名” 赋给它赋给它 3.变量的使用变量的使用, 要把它看成要把它看成 方法的调用方法的调用 来理解来理解 11.1.4 用例用例例例1: 委托对象当成局部变量例用委托对象当成局部变量例用class APP public static void Main() / Run r1; /定义一个定义一个Run类型的变量类型的变量r1 Run r1=new Run(Run1); /实例化实例化r1,并初始并初始 r1(); /执行执行Run1代码段代码段 A a=new A(); r1=a.Fun1; r1(); /执行了执行了a.Fun1(); public static v

7、oid Run1() Console.WriteLine(“in Run1”); class A public void Fun1()Console.WriteLine(“in Fun1”); 11.1.4用例用例例例2: 委托对象当成类委托对象当成类(结构结构)的数据成员使用的数据成员使用class APP public static void Main() B b1=new B(); b1.r=new Run(b1.Fun1); b1.r(); /执行了执行了 b1.Fun1() b1.r=Run1; b1.r();/相当于执行了相当于执行了APP.Run1(); public stati

8、c void Run1() Console.WriteLine(“in Run1”); class B public Run r; public void Fun1()Console.WriteLine(“in Fun1”); 11.1.4 用例用例例例3: 委托对象有参数和返回值时的使用委托对象有参数和返回值时的使用class APP public static void Main() C c1=new C(); =“张飞张飞”; c1. Active =hack; int result= c1. Active();/执行执行 Console.WriteLine(

9、result); /了解完成情况了解完成情况 public static int hack(string str) Console.WriteLine(“我是我是:0”, str); /完成砍的动作完成砍的动作 Console.WriteLine(“我在砍柴我在砍柴”); int 结果结果=0; return 结果结果; class C public string name; public Handle Active;11.1.5 进一步理解委托进一步理解委托 1.委托使委托使 动作动作 名词化名词化,是函数的进一步抽象是函数的进一步抽象 2. 委托的出现委托的出现,使程序能完成一些特殊的功能

10、使程序能完成一些特殊的功能如如: delegate 菜菜 加工方法加工方法(params 原料原料 f); class 厨师厨师 public 加工方法加工方法 加工加工; class 菜菜 class 原料原料 public string 名称名称; . class XX烹调大全烹调大全 static public 菜菜 煮煮(params 原料原料 f). static public 菜菜 炒炒(params 原料原料 f) static public 菜菜 蒸蒸(params 原料原料 f) 11.1.5 进一步理解委托进一步理解委托 1.委托使委托使 动作动作 名词化名词化,是函数的进

11、一步抽象是函数的进一步抽象 2. 委托的出现委托的出现,使程序能完成一些特殊的功能使程序能完成一些特殊的功能如如: class XX饭店饭店 public static void Main() 厨师厨师 张三张三=new 厨师厨师(); 原料原料 鱼鱼=new 原料原料(); 张三张三.加工加工= XX烹调大全烹调大全.煮煮; 菜菜 菜菜1=张三张三.加工加工(鱼鱼);/得到了煮鱼得到了煮鱼 张三张三.加工加工= XX烹调大全烹调大全. 炒炒; 菜菜 菜菜2=张三张三.加工加工(鱼鱼);/得到了炸鱼得到了炸鱼 / 将加工方法定义成委托的好处将加工方法定义成委托的好处: 使张三通过使张三通过”不

12、断地学习不断地学习”可以可以”学会学会”不同的烹调方法不同的烹调方法11.1.5 进一步理解委托进一步理解委托 3. 作为回调处理方法的一种机制作为回调处理方法的一种机制 如系统用此方法来接收消息如系统用此方法来接收消息,和处理事件和处理事件 例例: delegate void Handl(string 发送人发送人,string 消息消息); class 消息消息 public string 消息名消息名; public Handl 处理处理; class 系统系统 public static 消息消息 消息箱消息箱=new 消息消息5; public static void 加入消息队列加

13、入消息队列(stirng 消息名消息名,Handl 处理方法处理方法) /加入消息加入消息 static void 处理消息处理消息() /定期检查消息队列定期检查消息队列,有信就调用相应的处理方法有信就调用相应的处理方法. 执行执行 消息箱消息箱i.处理处理(发送人发送人1,消息消息1) class 本程序本程序 public static void Main() 系统系统.加入消息队列加入消息队列(“有我的信有我的信”,通知我通知我); public static void 通知我通知我(string 消息消息) console.writeLine(“事情为事情为:”+消息消息); 注意注

14、意: 本例仅为模拟系统信息处理本例仅为模拟系统信息处理,与实际情况差异较大与实际情况差异较大!(见见P311,E12-6)11.1.6 组播委托组播委托(广播广播,多播多播) 多个委托代码可以联合起来多个委托代码可以联合起来,实现执行一个委托变量而顺序调用多个代码段的能力实现执行一个委托变量而顺序调用多个代码段的能力添加添加 委托委托变量委托委托变量=待加入委托变量待加入委托变量1+待加入委托变量待加入委托变量2+; 委托变量委托变量+=待加入委托变量待加入委托变量; 委托变量委托变量+=new 委托委托(方法名方法名); 移除移除 委托变量委托变量 -=待加入委托变量待加入委托变量; 委托变

15、量委托变量 -=new 委托委托(方法名方法名); 例例: p311 E12-6 重要重要!,理解此知识点会更容易理解事件理解此知识点会更容易理解事件 11.2 事事件件 11.2.1 前言前言 11.2.2 定义和简单示例定义和简单示例 11.2.3 使用系统定义的类型使用系统定义的类型11.2.1 前言前言 想象一下想象一下: 生活中的事件生活中的事件 n历史历史 赤壁之战赤壁之战 9.18事变事变 新中国成立新中国成立n我的人生我的人生 当我当我XX岁生日岁生日, 当我大学毕业当我大学毕业,我的第一份薪水我的第一份薪水n门门 被打开被打开, 被关闭被关闭 n按钮按钮 被按下被按下,被放开

16、被放开 ,正被按下正被按下, 正被放开正被放开在软件中在软件中,为了让类为了让类 和类的实例和类的实例 之间更好的通信之间更好的通信,C#为我们定义了事件为我们定义了事件(event) 事件是一种对象间传递消息的一种方式事件是一种对象间传递消息的一种方式.通过事件通过事件, 可以将可以将 事件名与事件名与 具件事件联系起来具件事件联系起来. 如如: n 每个人都有每个人都有XX 岁生日事件岁生日事件, 但是每个人的但是每个人的XX岁生日所发生的都不相同岁生日所发生的都不相同.n 每个按钮都有每个按钮都有 按下按下,放开事件放开事件,都每个按钮按下都每个按钮按下,放开的处理和结果都不相同放开的处

17、理和结果都不相同.11.2.2 定义和简单示例定义和简单示例 事件是类的成员事件是类的成员,定义定义: 修饰符修饰符 event 委托类型委托类型 事件名事件名;.例例1: class Door public event EventHandler Opening ; /正在开门正在开门 public event EventHandler Opened ; /已开门已开门 public event EventHandler Closing; /正在关门正在关门 public event EventHandler Closed; /已关门已关门 例例2: class Button event Ev

18、entHandler Cliek ; /单击单击 event EventHandler DubClick; /双击双击 假设假设: EventHandler 委托原型为委托原型为 delegate void EventHandler(); 11.2.2 定义和简单示例定义和简单示例进一点完善进一点完善 门门 类类 ,加入两个动作加入两个动作: 开门开门 关门关门 例例1: class 门门 public event Event_Handler Opening ; /正在开门正在开门 public event Event_Handler Opened ; /已开门已开门 public event

19、 Event_Handler Closing; /正在关门正在关门 public event Event_Handler Closed; /已关门已关门 public void Open()if(Opening!=null) Opening(); /发送正在开门消息发送正在开门消息 /做开门的动作做开门的动作 / if(Opened!=null) Opened(); /发送门已被打开的消息发送门已被打开的消息 public void Close()if(Closing!=null) Closing (); /发送正在关门消息发送正在关门消息 /做关门的动作做关门的动作 / if(Closed!

20、=null) Closed (); /发送门已被关闭的消息发送门已被关闭的消息 11.2.2 定义和简单示例定义和简单示例如何使用如何使用 门门 例例1: class 房子房子 public static 门门 前门前门= new 门门(); ; /定义定义,并实例化一扇门并实例化一扇门 public static void Main() 前门前门.Opening += new Event_Handler(OnOpening);/把处理方法挂到把处理方法挂到Opening方法上去方法上去 前门前门.Opened += new Event_Handler(OnOpened);/把处理方法挂到把处

21、理方法挂到Opened方法上去方法上去 while(true) Console.WriteLine(“请输入动作请输入动作: 0-开门开门 C-关门关门 q-结束程序结束程序”); switch(Console.ReadLine() case “o”: 前门前门.Open();/开门开门 ;break; case “c”: 前门前门.Close();/关门关门;break; case “q”: return ; public static void OnOpening() Console.WriteLine(“门正被我打开门正被我打开!”); public static void OnOpen

22、ed() Console.WriteLine(“门已打开门已打开!”); . 11.2.2 定义和简单示例定义和简单示例修饰符修饰符 : 访问修饰符访问修饰符 public proteced private internal . 其它修饰符其它修饰符 new static virtual seadle override abstract 意义意义:(见类的成员修饰符见类的成员修饰符)事件类型事件类型: 事件的类型一定是委托类型事件的类型一定是委托类型; 其其:1.可以自行定义可以自行定义(见例见例1,例例2); 2.也可以使用系统已定义好的类型也可以使用系统已定义好的类型; 例例: deleg

23、ate void EventHandler(objcet send ,XXXEventArgs e) 参数参数: send 通常是指引发事件的对象通常是指引发事件的对象, e 是用来存放事件发生时传送来的数据是用来存放事件发生时传送来的数据 (注意注意: 类型为类型为XXXEventArgs ,均派生于均派生于EventArgs,这个系统定义好的类这个系统定义好的类) 返回值返回值 void 3. 也可以按也可以按 系统的要求系统的要求,派生参数派生参数 e 的类型的类型,以得到不同的委托以得到不同的委托 11.2.3 使用系统定义的委托类型使用系统定义的委托类型例例: 进一点改进进一点改进

24、例例1/定义委托定义委托 delegate void EventHandler(object send ,DoorEventArgs e);/处理处理”门门” 事件可能需要用到的数据对象事件可能需要用到的数据对象 class DoorEventArgs :EventArgs public string Message; public DoorEventArgs(string m) Message = m; 11.2.3 使用系统定义的委托类型使用系统定义的委托类型/门门的的定义定义 class Door public string 名称名称; public event EventHandler

25、 Opening ; /正在开门正在开门 public event EventHandler Opened ; /已开门已开门 public event EventHandler Closing; /正在关门正在关门 public event EventHandler Closed; /已关门已关门 public Door() public Door(string 名名)名称名称=名名; public void Open(object send) if(Opnening!=null) Opening(send, new DoorEventArgs(this.名称名称); /Do somethi

26、ng if(Opned!=null) Opened(send, new DoorEventArgs(this.名称名称); public void Close(object send) if(Closeing!=null) Closing(send, new DoorEventArgs(this.名称名称); /Do something if(Closed!=null) Closed(send, new DoorEventArgs(this.名称名称); 11.2.3 使用系统定义的委托类型使用系统定义的委托类型/事件驱动的事件驱动的”主程序主程序” class 房子房子 public str

27、ing 名称名称; public Door 大门大门; public 房子房子() public 房子房子(string 名名) 大门大门 = new Door(大门大门); /定义定义,并实例化一扇门并实例化一扇门 名称名称 = 名名; public void Init() 大门大门.Opening += new EventHandler(OnOpening);/把处理方法挂到把处理方法挂到Opening方法上去方法上去 大门大门.Opened += new EventHandler(OnOpened);/把处理方法挂到把处理方法挂到Opened方法上去方法上去 大门大门.Closing +

28、= new EventHandler(OnClosing); 大门大门.Closed += new EventHandler(OnClosed); public void OnOpening(object send, DoorEventArgs e) Console.WriteLine(0 的的1正在打开正在打开, (房子房子)send).名称名称, e.Message); public void OnOpened(object send, DoorEventArgs e) Console.WriteLine(0 的的1已打开已打开, (房子房子)send).名称名称, e.Message);

29、 11.2.3 使用系统定义的委托类型使用系统定义的委托类型/底层系统底层系统class App static 房子房子 h; public static void Main() Init();/系统初始化系统初始化 do Console.WriteLine(*); Console.WriteLine(请输入动作请输入动作: o-开门开门 c-关门关门 e-清除屏幕清除屏幕 q-结束程序结束程序); Console.WriteLine(*); switch (Console.ReadLine() case o: h.大门大门.Open(h) ;break; case c: h.大门大门.Clo

30、se(h);break; case e: Console.Clear(); break; case q: return; while (true); public static void Init() h = new 房子房子(陈公馆陈公馆); h.Init();/初始化初始化 11.3 事件访问器事件访问器n11.3.1 前言前言n11.3.2 定义定义11.3.1 前言前言n为什么使用事件访问器为什么使用事件访问器? 事件可以理解为是委托的一种特例事件可以理解为是委托的一种特例. 事件在使用上比委托受了一些限制事件在使用上比委托受了一些限制(为了更有意义的使用事件为了更有意义的使用事件)

31、1.事件的类的成员事件的类的成员 ,用用event 定义定义 委托是一种类型委托是一种类型 , 委托的实例才是类的成员委托的实例才是类的成员 delegate void Handle(); /委托委托 class A public event Handle click;/事件成员事件成员 public Handle Fun;/委托成员委托成员 2. 事件仅能用事件仅能用 += - = 加挂或脱离方法加挂或脱离方法 委托的实例对象可以用委托的实例对象可以用=号与方法挂勾号与方法挂勾,也可以使用也可以使用+=,也可以使用也可以使用- = 脱勾脱勾 click += new Handle(B.fun); click -= new Handle(B.fun); Fun=new Handle(); Fun=B.fun; Fun=null; Fun+=new Handle(B.fun); Fun-=new Handle(B.fun); Fun +=B.fun; 11.3.1 前言前言n为什么使用事件访问器为什么使用事件访问器?3. 系统在编译时会默认为

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论