C#委托及事件
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
单播vs.多播委托(续)
• 使用GetInvocationList 获取方法列表,此 列表是一个Delegate引用的数组 • 使用Delegate的Target及Method属性来确 定
– 哪个对象接受回调(callback) – 应该调用哪个方法
动手实验
• 委托
– 了解如何将委托映射到静态方法及实例方法 – 如何创建多路广播委托 – P104
add_MouseClicked method remove_MouseClicked method OnMouseClicked method
从客户的角度看事件
• 事件接收器:发生事情时被通知的程 序、对象或组件 • 事件发送器:引发事件的对象,如.Net运 行库中的对象 • 事件接收器中有方法负责处理事件 • 通过将方法加到事件发送器定义的委托 中来注册事件 • 如:Button的Click事件
SoundMaker Object MouseClicked method MouseClicked method
multicast delegate object multicast delegate object
stopButton object MouseClicked method MouseClicked method
事件
• • • • • • 概念 事件的场景 声明事件 注册到事件 触发事件 .Net Framework指南
Windows的消息机制
• 基于windows的应用程序是基于消息的
– windows是使用预定义的消息与应用程序通 信的 – 以前开发人员必须处理windows发送给应用 程序的消息 – VB及.Net将这些消息封装在了事件中,如果 要响应某个消息,就处理对应的事件
多播委托场景
1 - Change in switch position invokes switch’s OnFlip method
Switch Object
4 - OnFlipCallback method changes light1’s state
Light1 Object Light2 Object
调用委托
• 使用包含如下元素的语句进行调用
– 委托对象的名字 – 后面跟着括号括起来的传递给委托的参数
// 根据前面的声明及实例化过程,下面的语句调用了 //MyClass类中的静态方法Hello,使用了参数 //"World" a("World");
委托特征
• 委托的特征是它们是类型安全的,可以 确保被调用的的方法的签名是正确的 • 委托的实例可以是任何类型的任何对象 上的实例方法或静态方法,只要方法的 特征匹配与委托的特征即可
注册到事件
• 通过+=(Combine)注册到事件 • 通过-=(Remove)取消注册到事件
// Client’s method to handle the MouseClick event private void MouseClicked() { //... } //... // Client code to connect to MouseClicked event Mouse.MouseClicked += new MouseClickedEventHandler(MouseClicked); // Client code to break connection to MouseClick event Mouse.MouseClicked -= new MouseClickedEventHandler(MouseClicked);
委托的例子
• 一个通用的类,带有一个对象数组,可 将对象数组按升序排列,客户代码必需 要传入适当的对象比较的方法
委托的使用过程
• 使用类时,需要定义类,及其包含的字 段方法等。然后实例化该类的对象。 • 使用委托与类一样
– 定义所要使用的委托,即告诉编译器这种委 托类型代表了那种类型的方法 – 然后创建该委托的一个或多个实例
委托示例
• 简单的委托示例
– 将委托作为参数传递给一个方法中
• BubbleSorter示例
– 如何使用委托解决问题
多播委托
• 多播委托概念 • 多播委托场景( Multicast Delegate ) • 单播及多播委托 • 创建及调用多播委托 • C#相关语法 • 委托细节
概念
• 前面使用的委托都只包含一个方法调用 • 委托也可以包含多个方法,这种委托称 为多播委托 • 调用多播委托,就可以按顺序连续调用 多个方法 • 委托的签名必须返回void
对象通信方式
• 在开发基于对象的应用程序时,需要一 种对象间的通信方式
– 当一个对象中发生了有趣的事情是,需要通 知其他的对象发生了什么变化 – 将事件用作对象间的通信介质 – 在.Net中使用委托来对事件进行封装
事件场景
Mouse Object MouseClicked field
Invocation List:
– 子类中可以重写此方法
.Net框架指导(续)
public class SwitchFlippedEventArgs : EventArgs { //... } public delegate void SwitchFlippedEventHandler( object sender, SwitchFlippedEventArgs e); public event SwitchFlippedEventHandler SwitchFlipped;
OnFlipCallback method
4 - OnFlipCallback method changes light’s state
委托的概念
• 可将委托看作是一种新类型。当要把方 法传递给其它方法时使用
– 一个方法需要对另一个方法进行操作,此时 需要将第二个方法作为参数传递到第一个方 法中
• 因为.Net是类型安全的,所以不允许直接 将方法进行传递,所以需要将方法的细 节包装在新类型的对象中,即委托
C#的语法
• 在C#中,返回值为空的是多播委托 • 在C#中,使用+及-操作符在方法列表中 进行添加及移除
C#语法示例
MyDelegate a, b, c, d; a = new MyDelegate(Foo); b = new MyDelegate(Bar); c = a + b; // Compose two delegates to make another d = c - a; // Remove a from the composed delegate a += b; // Add delegate b to a's invocation list a -= b; // Remove delegate b from a's list
C#语法示例(续)
• 简单的委托示例的多播委托版本
创建及触发多播委托
// assign to c the composition of delegates a and b c = (MyDelegate2)Delegate.Combine(a, b); // assign to d the result of removing a from c d = (MyDelegate2)Delegate.Remove(c, a); // Iterate through c's invocation list // and invoke all delegates except a Delegate[] DelegateList = c.GetInvocationList(); for (int i = 0; i < DelegateList.Length; i++) { if (DelegateList[i].Target != aFoo1) { ((MyDelegate2) DelegateList[i])(); } }
实例化委托
• 使用new操作符创建委托对象 • 委托的构造函数总是带有一个参数,此 参数就是委托引用的方法
// 将委托实例化为(instantiating) MyClass类中的静 //态方法Hello MyDelegate1 a = new MyDelegate1(MyClass.Hello); // 将委托实例化为MyClass类的对象p中的实例方法 //AMethod MyClass p = new MyClass(); MyDelegate1 b = new MyDelegate1(p.AMethod);
单播vs.多播委托
• 所有的委托都有一个方法列表,当委托的触发 方法被调用时,这些方法就会被执行 • 单播委托:方法列表中只包含一个方法
– 直接派生自System.MulticastDelegate
• 多播委托:方法列表中包含多个方法
– 派生自System.MulticastDelegate – 多播委托包含两个静态方法:Combine及Remove用 于向方法列表中添加及移出方法
Switch Object
Light Object
OnFlip method
2 - OnFlip Method invokes delegate
Delegate object Delegate object
3 - Delegate invokes light’s OnFlipCallback method
声明委托
• 声明委托就是定义了一个类型,此类型 封装了一个有着特定参数集合即返回值 的方法的定义
// 为一个方法声明了一个委托,此方法接受一个 //string类型的参数,且返回值为空 delegate void MyDelegate1(string s);
委托是类
• 定义委托相当于定义了一个新类 • 所以可以在定义类的任何地方定义委托 • 委托实现为派生于基类 System.MulticastDelegate的类,此类又派 生于System.Delegate • 基类帮我们隐藏了实现委托功能的诸多 细节
委托及事件
青软实训 金澄
概述
• 委托 • 多播委托(muticast) • 事件 • 何时使用委托事件及接口
委托
• 委托的情景 • 声明委托 • Instantiating a Delegate • 调用委托
委托情景
1 - Change in switch position invokes switch’s OnFlip method
声明事件
• 声明事件的委托类型 • 声明事件
– 类似于委托类型的字段,加上event关键字
// MouseClicked delegate declared public delegate void MouseClickedEventHandler(); public class Mouse { // MouseClicked event declared public static event MouseClickedEventHandler MouseClicked; //... }
3 - delegate1 invokes light1’s OnFlipCallback Invocation list Multicast delegate1 object Multicast delegate1 object
5 - delegate2 is invoked
Multicast delegate2 object Multicast delegate2 object
OnFlip method
2 - OnFlip method invokes multicast delegate1
OnFlipCallback method OnFlipCallback method 7 - OnFlipCallback method changes light2’s state 6 - delegate2 invokes light2’s OnFlipCallback
触发事件
• 检查是否有注册到这个事件上的客户端
– 如果代表事件的字段为空,表示没有客户端
• 通过调用事件的委托来触发事件
if (MouseClicked != null) MouseClicked();
.Net框架指导
• 使用动词命名事件,使用Pascal规范 • 事件的参数的类扩展自System.EventArgs • 事件的委托返回值为空,并且有两个参wk.baidu.com数 • 使用protected virtual方法来触发事件