NO委托与事PPT课件

上传人:re****.1 文档编号:578486157 上传时间:2024-08-24 格式:PPT 页数:37 大小:2.08MB
返回 下载 相关 举报
NO委托与事PPT课件_第1页
第1页 / 共37页
NO委托与事PPT课件_第2页
第2页 / 共37页
NO委托与事PPT课件_第3页
第3页 / 共37页
NO委托与事PPT课件_第4页
第4页 / 共37页
NO委托与事PPT课件_第5页
第5页 / 共37页
点击查看更多>>
资源描述

《NO委托与事PPT课件》由会员分享,可在线阅读,更多相关《NO委托与事PPT课件(37页珍藏版)》请在金锄头文库上搜索。

1、L/O/G/O委托与事件委托与事件委托与事件委托与事件1vIn programming: situations need to execute a particular action, but dont know in advance which method, or even which object to call upon to execute. v例如:例如: 按下按钮确定,要激发一些对象去反应,但可按下按钮确定,要激发一些对象去反应,但可能存在一对多的关系,哪一个反应还不一定能存在一对多的关系,哪一个反应还不一定. 绑定到绑定到一个对象上不合适,那就可以把按钮连接到一个委托一个对象上

2、不合适,那就可以把按钮连接到一个委托上然后当程序执行时再启用特定需要的方法。上然后当程序执行时再启用特定需要的方法。2Console programs & GUI programs执行的区别v控制台程序控制台程序: 开始执行直到程序步骤结束开始执行直到程序步骤结束vGUI程序:事件驱动程序:事件驱动,用户接口用户接口,视用户操作行为作出不同响应,视用户操作行为作出不同响应,不同行为引发不同的方法调用。不同行为引发不同的方法调用。31 1、委托、委托 委托是一种特殊的类型(class),用途是来实现对一种方法的“封装”。在某种事件发生时,自动调用该方法。好处显然易见,它使用户可以自定义自己的方法

3、实现,通过封装,CLR会在相应事件激发时调用你定义的方法,实现自定义的功能。 C#中的委托类似于C或C+中的函数指针,但两者有本质区别:C或C+不是类型安全的,但C#中的委托是面向对象的,而且是类型安全的。从某种角度来讲,委托是一个引用类型,用来封装带有特定签名和返回类型的方法。 4 声明委托的具体格式如下:声明委托的具体格式如下: 访问修饰符 delegate 结果类型 委托标识符(形参列表); 委托类型可以在声明类的任何地方声明。 实例化委托实例化委托 委托使用new运算符来实例化且新创建的委托实例所引用的对象为以下情形之一:l 委托创建表达式中引用的静态方法l 委托创建表达式中引用的目标

4、对象(此对象不能为null)和实例方法l 另一个委托5Delegate void MyDelegate(int x);Class MyClassPublic static void Method1(int i)/自定义静态方法内容自定义静态方法内容Public void Method2(int i)/实例方法实例方法Class TestclassStatic void Maint()MyDelegate delegate1= new MyDelegate(MyClass.Method1);/静态方法静态方法实例化委托实例化委托MyClass class1 =new MyClass();MyDe

5、legate delegate2= new MyDelegate(class1.Method2);/实例方法实实例方法实例化委托例化委托MyDelegate delegate3=new MyDelegate(delegate2);/使用另一个委托实使用另一个委托实例化委托例化委托6 (3) 使用委托 实例化一个委托后,可以通过委托对象的名称及放入括号的要传递给委托的参数来调用委托对象。调用委托时,调用表达式的主表达式必须是委托类型的值。7vnamespace HR v v /定义员工结构体定义员工结构体v public struct Empv v public string Name; /员工

6、姓名员工姓名v public char Gender; /员工性别员工性别v public decimal Salary; / 员工薪水员工薪水v public Emp(string name, char gender, decimal salary) /构造员工对象构造员工对象v v this.Name = name;v this.Gender = gender;v this.Salary = salary; v v 8v /定义一个员工信息处理委托v public delegate void ProcessEmpDelegate(Emp emp);v /对员工信息进行管理v public

7、class HRManv v / 构造员工列表v ArrayList emplist = new ArrayList(); v /将员工添加到列表中v public void AddEmp(string name, char gender,decimal salary)v v emplist.Add(new Emp(name,gender,salary);v v /针对female员工,调用委托处理v public void ProcessFemaleEmp(ProcessEmpDelegate processEmp)v v foreach (Emp e in emplist) v v if

8、(e.Gender = F) v /调用委托处理v processEmp(e);v v 9vnamespace HRManClientv v using HR; v / 对员工信息进行处理v class SalaryTotallerv v int countEmp = 0;v decimal SalaryEmp = 0.0m;v /计算员工总工资及总人数v internal void AddEmpToTotal(Emp emp) v v countEmp += 1;v SalaryEmp += emp.Salary;v v /计算平均工资v internal decimal AverageSa

9、lary()v v return SalaryEmp / countEmp;v v 10v class Testv v /输出员工姓名v static void PrintName(Emp e)v v Console.WriteLine( 0, e.Name);v v /初始化员工列表v static void InitEmps(HRMan hr)v v hr.AddEmp(zhangsan,F,1200);v hr.AddEmp(lisi,M,2631);v hr.AddEmp(wangwu,F,3254);v hr.AddEmp(qianliu,M,800);v 11v / Main函数v

10、 static void Main()v v HRMan hrman = new HR.HRMan();v / 初始化员工列表v InitEmps(hrman); v / 输出female员工姓名v Console.WriteLine(femal employeer name:);v / 创建委托对象并与静态方法进行关联v hrman.ProcessFemaleEmp(new ProcessEmpDelegate(PrintName);v / 通过实例化SalaryTotaller对象得到平均薪水v SalaryTotaller totaller = new SalaryTotaller();

11、v / 创建一个委托对象,并且与非静态方法关联v hrman.ProcessFemaleEmp(new ProcessEmpDelegate(totaller.AddEmpToTotal);v Console.WriteLine(Average female salary: RMB 0元,v totaller.AverageSalary();v Console.ReadLine();v 12程序结构程序结构vnamespace HR结构体Emp:员工姓名、性别、薪水委托ProcessEmpDelegate:无返回,参数为emp类HRman:AddEmp方法增加员工,ProcessFemaleE

12、mp方法的方法的参数为委托参数为委托;vNamespace HRManClientclass SalaryTotallerAddEmpToTotal方法方法emp结构做参数计算员结构做参数计算员工总数;工总数; AverageSalary方法计算员工平均工资方法计算员工平均工资class TestPrintName方法emp结构参数输出员工姓名; InitEmps方法HRman参数,初始化员工列表;Main函数:初始化员工列表、用委托实例输出女员工姓名、实力委托输出女员工平均工资1314Example 6.5v/声明一个委托vpublic delegate void HelloDelegate

13、(string name); vclass Program vv private static void HelloEng(string name) /英文版Hellov vConsole.WriteLine(Hello, + name);vvprivate static void HelloChin(string name) /中文版HellovvConsole.WriteLine(您好 + name);v v/此方法接受一个委托类型变量v private static void Hello(string name, HelloDelegate MakeHello)v v MakeHello

14、(name);v v static void Main(string args) v v Hello(Jimes, HelloEng);v Hello(张三, HelloChin);v Console.ReadLine();v v15Multicasting多重委托多重委托v有时候委托可以组合有时候委托可以组合vmyMulticastDelegate = Writer + Logger;v vmyMulticastDelegate += Transmitter;16Example 12-2. Combining delegatesv public class MyClassWithDelega

15、tev v public delegate void StringDelegate( string s );v v public class MyImplementingClassv v public static void WriteString( string s )v v Console.WriteLine( Writing string 0, s );v v public static void LogString( string s )v v Console.WriteLine( Logging string 0, s );v v public static void Transmi

16、tString( string s )v v Console.WriteLine( Transmitting string 0, s );v v 17vpublic static void Main( ) vMyClassWithDelegate.StringDelegate Writer, Logger, Transmitter; MyClassWithDelegate.StringDelegate myMulticastDelegate;vWriter = new MyClassWithDelegate.StringDelegate(v MyImplementingClass.WriteS

17、tring );v Logger = new MyClassWithDelegate.StringDelegate(vMyImplementingClass.LogString );vTransmitter = new MyClassWithDelegate.StringDelegate(v MyImplementingClass.TransmitString );vWriter( String passed to Writern );vLogger( String passed to Loggern );vTransmitter( String passed to Transmittern

18、);vConsole.WriteLine( myMulticastDelegate = Writer + Logger );18vmyMulticastDelegate = Writer + Logger;vmyMulticastDelegate( First string passed to Collector );vConsole.WriteLine(nmyMulticastDelegate += Transmitter ); v vmyMulticastDelegate += Transmitter;vmyMulticastDelegate( Second string passed t

19、o Collector );vConsole.WriteLine( nmyMulticastDelegate -= Logger );vmyMulticastDelegate -= Logger;vmyMulticastDelegate( Third string passed to Collector );19委托最常用的一个领域是用来声明委托最常用的一个领域是用来声明“事件事件”,或者说:委托是事件的基础或者说:委托是事件的基础20什么是事件什么是事件eventvsomething happens and you must respond to it.vE.g : button push,

20、 menu selection, the completion of a file transfer.v能放到能放到WPF中的大多数控件以及中的大多数控件以及Window类本身,类本身,都允许在发生特定事件的时候运行代码都允许在发生特定事件的时候运行代码21事件的本质事件的本质 v事件是软件系统里的两个子系统之间,或者两个模事件是软件系统里的两个子系统之间,或者两个模块之间,或者两个对象之间发送消息,并处理消息块之间,或者两个对象之间发送消息,并处理消息的过程。的过程。v在面向对象的世界里,就可以统一认为是两个对象在面向对象的世界里,就可以统一认为是两个对象之间的行为。之间的行为。 v两个对象

21、之间发送的这种消息,对发送方来讲是产两个对象之间发送的这种消息,对发送方来讲是产生一个事件,对接受方来讲是需要处理某个事件。生一个事件,对接受方来讲是需要处理某个事件。这种消息可以是用户操作产生的或者软件系统里的这种消息可以是用户操作产生的或者软件系统里的某个对象产生的。某个对象产生的。 22对对象象一一产产生生一一个个事事件件,这这个个事事件件发发生生以以后后需需要要对对象象二二执执行某种动作。这就是事件机制。行某种动作。这就是事件机制。对对象象一一是是事事件件的的产产生生者者,或或者者发发送送者者;对对象象二二是是事事件件的的接接收收者者或或者者订订阅阅者者。对对象象一一产产生生某某种种消

22、消息息,需需要要对对象象二二响应并处理这消息,这就是事件的本质。响应并处理这消息,这就是事件的本质。 一一件件事事情情发发生生了了,可可能能对对某某些些客客体体(Client)产产生生影影响响,也也可可能能没没有有任任何何影影响响。如如果果事事情情发发生生了了、并并对对客客体体产产生生了了影影响响,这这时时候候,我我们们就就应应该该拿拿出出影影响响这这一一影影响响的的办办法法来。来。2324例子:例子:v大楼的火警响了(火警鸣响这一事件发生),它大楼的火警响了(火警鸣响这一事件发生),它产生的影响是让楼内的所有人员都听到了警报声,产生的影响是让楼内的所有人员都听到了警报声,楼内的人纷纷拿出自己

23、响应这一影响的方法来楼内的人纷纷拿出自己响应这一影响的方法来普通职员们飞奔出大楼,而消防人员却向相反的普通职员们飞奔出大楼,而消防人员却向相反的方向跑,冲向最危险的火场。方向跑,冲向最危险的火场。v我们把这种套路称为我们把这种套路称为“事件响应机制事件响应机制”,用于响应,用于响应事件所造成的影响而采取的行动简称为事件所造成的影响而采取的行动简称为“事件响事件响应方法应方法”。v特别注意:特别注意:员工逃跑和消防员冲向火场都是对警员工逃跑和消防员冲向火场都是对警号鸣响这一事件的响应方法,而非事件所产生的号鸣响这一事件的响应方法,而非事件所产生的影响。影响。F小问题:火警响了,我们为什么会跑呢?

24、小问题:火警响了,我们为什么会跑呢?F因为我们时刻关心着警报会不会响这个事件。因为我们时刻关心着警报会不会响这个事件。2425vnamespace EventSample / 委托是事件的基础,是通知的发送方与接收方双方共同遵守的委托是事件的基础,是通知的发送方与接收方双方共同遵守的“约定约定” delegate void FireAlarmDelegate(); class Building / 大楼(类)大楼(类) / 声明事件:事件以委托为基础声明事件:事件以委托为基础 public event FireAlarmDelegate FireAlarmRing; /大楼失火,引发火警鸣响事

25、件大楼失火,引发火警鸣响事件 public void OnFire() this.FireAlarmRing(); class Employee / 员工(类)员工(类) / 这是员工对火警事件的响应,即员工的这是员工对火警事件的响应,即员工的Event handler。注意与委托的。注意与委托的匹配。匹配。 public void RunAway() Console.WriteLine(Running awary.); 2526v/ 消防员(类)消防员(类) class Fireman / 这是消防员对火警事件的响应,即消防员的这是消防员对火警事件的响应,即消防员的Event handler

26、。注意与委托的匹配。注意与委托的匹配。 public void RushIntoFire() Console.WriteLine(Fighting with fire.); class Program static void Main(string args) Building sigma = new Building(); Employee employee = new Employee(); Fireman fireman = new Fireman(); / 事件的影响者事件的影响者订阅订阅事件,开始关心这个事件发生没发生事件,开始关心这个事件发生没发生 sigma.FireAlarmR

27、ing+=new FireAlarmDelegate(employee.RunAway); sigma.FireAlarmRing += new FireAlarmDelegate(fireman.RushIntoFire); /由你来放火!由你来放火! Console.WriteLine(Please input FIRE to fire the building.); string str = Console.ReadLine(); if (str.ToUpper()=FIRE) sigma. OnFire(); 26v需要在事件中使用的代码有需要在事件中使用的代码有5部分部分委委托托类类

28、型型声声明明:事事件件和和事事件件处处理理程程序序必必须须有有共共同同的的签签名名和和返返回回类类型型,它们通过委托声明进行描述它们通过委托声明进行描述事事件件处处理理程程序序声声明明:这这些些在在订订阅阅者者类类的的方方法法中中的的描描述述会会在在事事件件触触发发时时被被执执行行,它它们们可可以以是是匿匿名名方方法法或或lambda表达式表达式事事件件声声明明:这这个个事事件件发发布布者者类类中中的的声明保存并调用事件处理程序声明保存并调用事件处理程序触触发发事事件件的的代代码码:发发布布者者类类中中的的这这段段代代码码调调用用事事件件导导致致它它调调用用事事件件处处理程序理程序27v事件设

29、计是随同委托使用的,所以事件的类型必须是一个委事件设计是随同委托使用的,所以事件的类型必须是一个委托,而且必须在声明前附加托,而且必须在声明前附加event关键字关键字event delegateTypeName eventName/定义事件,该事件引发此委托类型的事件处理函数 v例如:例如:v也可以声明多个事件也可以声明多个事件public event EventHandler MyEvent1, MyEvent2, OtherEvent;v还可以声明静态事件还可以声明静态事件public static event EventHandler Elapsed;课本示例:将StopMachine

30、ryDelegate委托转移到一个新类中class TemperatureMonitorpublic delegate void StopMachineryDelegate();public event StopMachineryDelegate MachineOverheating;.28事件的订阅与取消事件的订阅与取消 (1) 订阅事件 事件的订阅是通过为事件加上左操作符事件的订阅是通过为事件加上左操作符“+=”“+=”来实现的来实现的,如: MyString mystring = new MyString(); mystring.Changed += new EventHandler(m

31、ystring_Changed (object sender, EventArgs e); 只要事件被触发,所订阅的方法就会被调用。 (2) 取消订阅 事件的撤消则采用左操作符事件的撤消则采用左操作符“- =”“- =”来实现的:来实现的: mystring.Changed -= new EventHandler(mystring_Changed); 请参考示例代码体会事件的用法。29vnamespace ConsoleApplication1vvpublic class MyStringv v private string _text = ;v /定义事件的委托v public delega

32、te void ChangedEventHandler(object sender, EventArgs e);v /声明事件v public event ChangedEventHandler Changed;v / 用以触发事件v protected virtual void OnChanged(EventArgs e)v v if (this.Changed != null)v this.Changed(this, e);v 30v /定义Text属性v public string Textv v get return this._text; v setv v this._text =

33、value;v /当Text属性被修改时,触发Changed事件v this.OnChanged(new EventArgs();v v v 31v class Programv v static void Main(string args)v v MyString mystring = new MyString();v /将事件处理程序添加到事件的调用列表中即订阅事件v mystring.Changed += new MyString.ChangedEventHandler(mystring _Changed); v string str = ;v while (str != quit)v

34、v Console.WriteLine(please enter a string:);v str = Console.ReadLine();v mystring.Text = str;v v v /事件处理函数v private static void mystring_Changed(object sender, EventArgs e)v v Console.WriteLine(text has been changed :0n ,(MyString)sender).Text);v v 3233理解理解WPF用户界面事件用户界面事件v用于生成用于生成GUI的的.NET Framework

35、类和控件广类和控件广泛运用了事件泛运用了事件vWPF Button类派生自类派生自ButtonBase类,继承了类,继承了一个名为一个名为Click的的public事件事件v事件的类型是:事件的类型是:public delegate void RoutedEventHandler(Object sender, RoutedEventArgs e);34vButton类的定义如下:类的定义如下:public class ButtonBase: . public event RoutedEventHandler Click; .public class Button: ButtonBase .35vprivate void button1_Click(object sender, RoutedEventArgs e)v各种各种GUI控件生成的事件总是遵循相同的模式控件生成的事件总是遵循相同的模式v事件是一个委托类型,它的签名有一个事件是一个委托类型,它的签名有一个void类型类型和两个参数和两个参数v第一个参数用来保存触发事件的对象的引用第一个参数用来保存触发事件的对象的引用v第二个参数用来保存有关状态是否合适的信息第二个参数用来保存有关状态是否合适的信息3637

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 办公文档 > 工作计划

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号