登山-C#-再讨论事件,理清事件和委托的关系,理清EventHandler<T>和传统事件的关系
来源:互联网 发布:华晨宇全球歌迷会淘宝 编辑:程序博客网 时间:2024/04/29 12:46
以前在写程序时,总是稀里糊涂的用着委托和事件,但总是不能很清楚的理清出他们之间的关联,只是知道事件是建立在委托的基础上的。
之前也写过一篇关于事件的文章,现在看来太浅了,只是依葫芦画瓢,知道怎么去用而已,而却不知道所以然。其中的一些细节也没有注意到,现在看看是比较肤浅的。
今天再花点时间彻底搞清楚他们之间的关系。
在接触事件这个概念时,经常被绕晕,什么delegate,event,EventHandler,Handler之类一堆词。
常常有这样的疑惑,都说事件从委托来,那怎么用的时候没有看到delegate声明委托啊,直接就是EventHandler了
这就涉及到一个概念的理解了
在C#中内置了一个EventHandler<T>范型
他的真面目其实是这样的
public delegate voidEventHandler<T>(object sender, T e)
其实他就是声明了一个委托。
我们不用EventHandler<T>范型也是可以构建事件的。
编程中经常遇到的场景是FormA调用FormB,然后从FormB返回一些值给FormA,供其使用。今天就使用这个场景做说明。
先看单纯使用委托完成的事件
首先自定义一个类用户信息的载体
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace EventDemo{ /// <summary> /// 定义CustomerEventArgs,作为消息发布者和消息订阅者之间传递消息的媒介 /// 这里是传递的string类型,也可以替换为其他的类 /// </summary> public class CustomerEventArgs:EventArgs { private string msg; public CustomerEventArgs(string s) { msg = s; } /// <summary> /// Message暴露给外界使用 /// </summary> public string Message { get { return msg; } set { Message = msg; } } }}
接下来定义一个消息的发布者,也就是FormB代表的需要信息的一方
using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Windows.Forms;namespace EventDemo{ public partial class OldEventPubliser : Form { public delegate void CustomerEventHandler(object sender, CustomerEventArgs e); //这里event的意义在于,如果加了event,外面的类不能通过OldEventPubliser的对象直接调用RaisingMessage //event关键字,限定了外界对委托变量只能使用+=或-=操作符,对于其他的比如赋值或者调用都会被视为错误 public event CustomerEventHandler RaisingMessage; public OldEventPubliser() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { if (RaisingMessage != null) { CustomerEventArgs ce = new CustomerEventArgs(this.textBox1.Text); RaisingMessage(sender, ce); this.Close(); } } }}再定义消息的订阅者,也就是FormA代表的一方
using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Windows.Forms;namespace EventDemo{ //演示旧的事件的使用方式,OldEventSubscriber是事件订阅者身份 public partial class OldEventSubscriber : Form { public OldEventSubscriber() { InitializeComponent(); } /// <summary> /// 当发布者执行了发布消息动作之后,就会执行到此处,处理接收到消息的地方 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void WhenIGetMessage(object sender, CustomerEventArgs e) { this.textBox1.Text = e.Message; } private void button1_Click(object sender, EventArgs e) { OldEventPubliser publiser = new OldEventPubliser(); //订阅了消息 publiser.RaisingMessage += WhenIGetMessage; publiser.ShowDialog(); } }}在这里我们就没有使用EventHandler<T>范型,同样完成了任务,在这个基础上再去理解EventHandler<T>完成的事件就很容易了。
这里我们还顺道解释了一下event关键字在其中起到的作用,这也是容易困扰人去理解事件的地方。
0 0
- 登山-C#-再讨论事件,理清事件和委托的关系,理清EventHandler<T>和传统事件的关系
- 委托和事件的关系
- 理清apply(),call()的区别和关系
- 理清apply(),call()的区别和关系
- 理清apply(),call()的区别和关系
- 理清WebSocket和HTTP的关系
- 委托、事件和回调的关系
- 委托、事件和回调的关系
- 理清全表扫描和高水位,行预取的关系
- android cts理清testpackage和文件名的对应关系
- 读 《理清技术、业务和架构的关系》有感
- 事件与委托的关系
- 委托、事件、接口等之间的关系和区别[转载]
- 消息和事件的关系
- C#事件与委托的关系【使用】
- 理清Asp与XML的关系
- 理清ISIS、CLNS、NSAP、NET的关系
- 理清gcc、libc、libstdc++的关系
- Android将本地工程提交到指定Git仓库上进行代码管理
- 《redis实战》读书笔记-第五、六、七、八章:应用实例
- [leetCode刷题笔记]2017.02.28
- 搭建vue2.0+vuex+vue-router+babel+webpack环境
- win2003服务器磁盘管理基础知识
- 登山-C#-再讨论事件,理清事件和委托的关系,理清EventHandler<T>和传统事件的关系
- Eclipse/MyEclipse 最最常用的快捷键
- <21.01>MongoDB数据库
- Map排序,获取map的第一值,根据value取key等操作(数据预处理)
- Mysql安装总结
- Android中使用MediaPlayer播放音乐状态转换
- 微软的dotnet-new工具可以使创建JavaScript Web 程序变得更简单
- 多用户并发测试程序
- POJ 1860 Currency Exchange(最短路)