2018-05-01 10:49:47
委托是一种类型,而事件是一个类或结构的成员,如同字段,属性。必须在类或结构中声明。
引申 - Observe 观察者模式 Publish/Subscribe 发布-订阅模式
一 基本形式
1. 如上图所示,声明委托,类中构建 事件 及 触发代码
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace EventDemo 8 { 9 // Event 1 of 5 elements -- deletegate declare 10 delegate void Handler(); 11 12 // Publisher 13 // 1. Event declare 14 // 2. fire event code 15 class Incrementer 16 { 17 public event Handler eventPub; // create event 18 19 // 触发事件的代码 20 public void DoIncrement() 21 { 22 for(int i = 0; i < 100; i++) 23 { 24 if (i % 12 == 0 && eventPub != null) 25 eventPub(); 26 } 27 } 28 29 } 30 }
2. 订阅者中 创建事件处理程序 及 注册事件。
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace EventDemo 8 { 9 /* 10 * 订阅者 11 * 1.事件处理程序 12 * 2.构造器中注入 Publisher,构造代码中给事件添加处理程序方法。订阅事件。 13 */ 14 class subscribeCode 15 { 16 public int DozoneCount { get; private set; } 17 18 // 事件处理程序 19 void IncrementCount() 20 { 21 DozoneCount++; 22 } 23 24 // 构造器 订阅事件 25 public subscribeCode(Incrementer inc) 26 { 27 DozoneCount = 0; 28 inc.eventPub += IncrementCount; 29 } 30 31 } 32 }
二 EventHandler
public vodi EventHandler ( Object sender, EventArgs e)
(this, null ) 来匹配一致
三 需要传输数据时 自定义 EventArgs 派生类。
1. 首先定义 派生子 EventArgs 的类
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace EventDemo.CustomerDefine 8 { 9 /* public void EventHandler(Object sender, EventArgs e) 10 * EventArgs 被设计为不能传递任何参数, 11 * 需要声明派生自 EventArgs 的类,自定义保存数据的字段。 12 * 13 * 命名规范 以 Args结尾 14 */ 15 public class CustomerEventArgs : EventArgs 16 { 17 public int DestinateData { get; set; } 18 } 19 }
2. 其余步骤同上,注意定义 事件处理程序时
1)返回值为 void。
2) Publisher
View Code
3)Subscribe
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace EventDemo.CustomerDefine 8 { 9 class SubscribeClass 10 { 11 public int transferData { get; set; } 12 13 public void AccountMethod(Object send, CustomerEventArgs e) 14 { 15 Console.WriteLine("{0} transfer data,/t {1} send", 16 e.DestinateData, send.ToString()); 17 transferData++; 18 } 19 public SubscribeClass(PublisherClass pc) 20 { 21 transferData = 0; 22 pc.handler += AccountMethod; 23 } 24 } 25 }
注意 移除事件处理程序 是从最后的寻找第一个匹配的,类似于 委托的方法移除
高级用法, 事件访问器
将 += -= 改变。 让事件执行任何我们希望的自定义代码。
两个访问器 add remove
声明事件访问器 类似于 声明一个属性 返回 void
public event EventHandler CountedADozen
{
add
{ ... } // 执行 += 运算符
remove
{ ... } // 执行 -= 运算符
}
声明之后,事件不包含任何内嵌委托对象。必须实现自己的机制来存储和移除时间注册的方法。