C#中委托和事件的区别
大致来说,委托是一个类,该类内部维护着一个字段,指向一个方法。事件可以被看作一个委托类型的变量,通过事件注册、取消多个委托或方法。本篇分别通过委托和事件执行多个方法,从中体会两者的区别。
□ 通过委托执行方法
class Program
{
static void Main(string[] args)
{
Example example = new Example();
example.Go();
Console.ReadKey();
}
}
public class Example
{
public delegate void DoSth(string str);
internal void Go()
{
//声明一个委托变量,并把已知方法作为其构造函数的参数
DoSth d = new DoSth(Print);
string str = "Hello,World";
//通过委托的静态方法Invoke触发委托
d.Invoke(str);
}
void Print(string str)
{
Console.WriteLine(str);
}
}
以上,
○ 在CLR运行时,委托DoSth实际上就一个类,该类有一个参数类型为方法的构造函数,并且提供了一个Invoke实例方法,用来触发委托的执行。
○ 委托DoSth定义了方法的参数和返回类型
○ 通过委托DoSth的构造函数,可以把符合定义的方法赋值给委托
○ 调用委托的实例方法Invoke执行了方法
但,实际上让委托执行方法还有另外一种方式,那就是:委托变量(参数列表)
public class Example
{
public delegate void DoSth(object sender, EventArgs e);
internal void Go()
{
//声明一个委托变量,并把已知方法作为其构造函数的参数
DoSth d = new DoSth(Print);
object sender = 10;
EventArgs e = new EventArgs();
d(sender, e);
}
void Print(object sender, EventArgs e)
{
Console.WriteLine(sender);
}
}
以上,
○ 委托DoSth的参数列表和方法Print的参数列表还是保持一致
○ 委托DoSth中的参数object sender通常用来表示动作的发起者,EventArgs e用来表示动作所带的参数。
而实际上,委托变量(参数列表),事件就是采用这种形式执行方法的。
□ 通过事件执行方法
public class Example
{
public delegate void DoSth(object sender, EventArgs e);
public event DoSth myDoSth;
internal void Go()
{
//声明一个委托变量,并把已知方法作为其构造函数的参数
DoSth d = new DoSth(Print);
object sender = 10;
EventArgs e = new EventArgs();
myDoSth += new DoSth(d);
myDoSth(sender, e);
}
void Print(object sender, EventArgs e)
{
Console.WriteLine(sender);
}
}
以上,
○ 声明了事件myDoSth,事件的类型是DoSth这个委托
○ 通过+=为事件注册委托
○ 通过DoSth委托的构造函数为事件注册委托实例
○ 采用委托变量(参数列表)这种形式,让事件执行方法
而且,通过+=还可以为事件注册多个委托。
public class Example
{
public delegate void DoSth(object sender, EventArgs e);
public event DoSth myDoSth;
internal void Go()
{
//声明一个委托变量,并把已知方法作为其构造函数的参数
DoSth d = new DoSth(Print);
DoSth d1 = new DoSth(Say);
object sender = 10;
EventArgs e = new EventArgs();
//为事件注册多个委托
myDoSth += new DoSth(d);
myDoSth += new DoSth(d1);
myDoSth(sender, e);
}
void Print(object sender, EventArgs e)
{
Console.WriteLine(sender);
}
void Say(object sender, EventArgs e)
{
Console.WriteLine(sender);
}
}
以上,通过+=为事件注册1个或多个委托实例,实际上,还可以为事件直接注册方法。
public class Example
{
public delegate void DoSth(object sender, EventArgs e);
public event DoSth myDoSth;
internal void Go()
{
object sender = 10;
EventArgs e = new EventArgs();
//为事件注册多个委托
myDoSth += Print;
myDoSth += Say;
myDoSth(sender, e);
}
void Print(object sender, EventArgs e)
{
Console.WriteLine(sender);
}
void Say(object sender, EventArgs e)
{
Console.WriteLine(sender);
}
}
□ 通过EventHandler执行方法
先来看EventHandler的源代码。
可见,EventHandler就是委托。现在就使用EventHandler来执行多个方法。
public class Example
{
public event EventHandler myEvent;
internal void Go()
{
object sender = 10;
EventArgs e = new EventArgs();
//为事件注册多个委托
myEvent += Print;
myEvent += Say;
myEvent(sender, e);
}
void Print(object sender, EventArgs e)
{
Console.WriteLine(sender);
}
void Say(object sender, EventArgs e)
{
Console.WriteLine(sender);
}
}
总结:
○ 委托就是一个类,也可以实例化,通过委托的构造函数来把方法赋值给委托实例
○ 触发委托有2种方式: 委托实例.Invoke(参数列表),委托实例(参数列表)
○ 事件可以看作是一个委托类型的变量
○ 通过+=为事件注册多个委托实例或多个方法
○ 通过-=为事件注销多个委托实例或多个方法
○ EventHandler就是一个委托
C#中委托和事件的区别的更多相关文章
- C#中委托和事件的区别实例解析
这篇文章主要介绍了C#中委托和事件的区别,并分别以实例形式展示了通过委托执行方法与通过事件执行方法,以及相关的执行流程与原理分析,需要的朋友可以参考下 本文实例分析了C#中委托和事件的区别,分享给大家 ...
- 委托、Lambda表达式、事件系列06,使用Action实现观察者模式,体验委托和事件的区别
在"实现观察者模式(Observer Pattern)的2种方式"中,曾经通过接口的方式.委托与事件的方式实现过观察者模式.本篇体验使用Action实现此模式,并从中体验委托与事件 ...
- c# 委托与事件的区别
委托与事件的区别 委托和事件没有可比性,因为委托是数据类型,事件是对象(可以理解为对委托变量的封装.),下面说的是委托的对象(用委托方式实现的事件)和(标准的event方式实现)事件的区别.事件的内部 ...
- c#之委托和事件的区别
1.什么是委托,这里就不做介绍了,如果想了解可以查看博客:http://www.cnblogs.com/xiaoxiaogogo/p/3571494.html 下面开始对事件进行介绍 1.定义事件以及 ...
- c#中委托和事件(转)
C# 中的委托和事件 引言 委托 和 事件在 .Net Framework中的应用非常广泛,然而,较好地理解委托和事件对很多接触C#时间不长的人来说并不容易.它们就像是一道槛儿,过了这个槛的人,觉得真 ...
- c#中委托和事件区别
委托和事件相同的功能 class Dem5 { public Action deHandler; public event Action eveHa; public Dem5() { deHandle ...
- c#中委托和事件(续)(转)
本文将讨论委托和事件一些更为细节的问题,包括一些大家常问到的问题,以及事件访问器.异常处理.超时处理和异步方法调用等内容. 为什么要使用事件而不是委托变量? 在 C#中的委托和事件 中,我提出了两个为 ...
- C#一些知识点:委托和事件的区别
在C#中,委托和事件是比较容易混淆的两个知识点,本篇博客就记录一下委托和事件之间的区别. 定义上的区别 委托:委托实际上是一个类,用来表示一个函数,可以理解为C++中的函数指针. 事件:事件是一个修饰 ...
- C#中委托和事件
目 录 将方法作为方法的参数 将方法绑定到委托 更好的封装性 限制类型能力 范例说明 Observer 设计模式简介 实现范例的Observer 设计模式 .NET 框架中的委托与事件 为什么委托定义 ...
随机推荐
- Ubuntu屏幕分辨率无1920 1080
xrandr 没有1920X1080分辨率,所以手动添加一个1080P分辨率,先输入“cvt 1920 1080”命令,查询一下1080P分辨率的有效扫描频率 然后 sudo xrandr --new ...
- VMware 常见问题及解决办法
Ø 简介 本文介绍使用 VMware 虚拟机时常见的问题及解决办法,主要包括: 1. 虚拟机操作系统装好后,每次进入虚拟机还进入安装程序 2. 虚拟机不能与主机复制粘帖 3. 解决错误: ...
- echo 输入背景和字体常用方法
ECHO输出背景颜色以及文字颜色输出格式: echo -e "\033[字背景颜色;文字颜色m字符串\033[0m"例如: echo -e & ...
- es6常用语法学习笔记
1.let和const的常规使用 let声明的变量不存在预解析 let声明的变量不允许重复使用(在同一个作用域内) ES6引入了块级作用域{},块内部定义的变量,在外部是不可以访问到的 使用let在f ...
- UOJ #310「UNR #2」黎明前的巧克力
神仙题啊... UOJ #310 题意 将原集合划分成$ A,B,C$三部分,要求满足$ A,B$不全为空且$ A$的异或和等于$ B$的异或和 求方案数 集合大小 $n\leq 10^6$ 值域$v ...
- ef mysql
App.config <configuration> <configSections> <!-- For more information on Entity Frame ...
- JAVA进阶17
---恢复内容开始--- 间歇性混吃等死,持续性踌躇满志系列-------------第17天 1.递归结构 递归是一种常见的解决问题的方法,即把问题逐渐简单化.递归的基本思想就是自己就是“自己调用自 ...
- gojs常用API-画布定义
持续更新中 基础画布定义API画布初始位置 initialContentAlignment: go.Spot.Center,画布位置,定义后就不能拖动画布了,画布位置交由gojs管理 contentA ...
- 项目Alpha冲刺(2/10)
1.项目燃尽图 2.今日进度描述 项目进展 完成数据库和服务器的连接部分,完成了一些应用的基本功能. 问题困难 第一次使用服务器,配置环境部署项目都花了很长时间,学习中存在许多问题. 心得体会 应该早 ...
- python安装过程中的一些问题
因为看到大神的教程是基于python V2.7,下载该版本且安装成功. 安装目录: https://www.python.org/download/releases/2.7/ 根据系统进行安装包下载 ...