博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C#中委托和事件的区别
阅读量:7209 次
发布时间:2019-06-29

本文共 3102 字,大约阅读时间需要 10 分钟。

大致来说,委托是一个类,该类内部维护着一个字段,指向一个方法。事件可以被看作一个委托类型的变量,通过事件注册、取消多个委托或方法。本篇分别通过委托和事件执行多个方法,从中体会两者的区别。

 

□ 通过委托执行方法

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就是一个委托

转载地址:http://hhrum.baihongyu.com/

你可能感兴趣的文章
都是假期惹的祸,该如何安慰自己?
查看>>
从零开始学JavaScript二(基本概念)
查看>>
Android AlarmManager(全局定时器/闹钟)指定时长或以周期形式执行某项操作
查看>>
js中的var
查看>>
年终知识分享——移动应用开发
查看>>
Centos 5.5 安装Mysql5.5过程
查看>>
网络爬虫基本原理(二)
查看>>
AndroidUI组件之ListView小技巧
查看>>
使用ThinkPHP框架高速开发站点(多图)
查看>>
解决iframe缓存
查看>>
mysql事物
查看>>
微软开源代码
查看>>
ssh 实体关系分析确立(ER图-实体关系图)
查看>>
shell语法简单介绍
查看>>
iOS捕获异常,常用的异常处理方法
查看>>
Struts2(九)OGNL标签一与Struts2标签
查看>>
双网卡绑定-bond0
查看>>
利用扩展事件进行调优和Troubleshooting PPT分享
查看>>
finger-guessing game:1场景搭建
查看>>
axure7.0 汉化包下载
查看>>