1. 委托

事件是利用委托来定义的,因此先解释委托。委托其实是一个类,它与其他类如string(引用类型)等没有本质区别,string代表的是字符串,委托则代表的是一类方法,这类方法具有相同返回类型和相同参数。例:有如下委托定义

  public delegate void CalculatorHandler(int x,int y);

从CalculatorHandler这个委托的定义可以看出,它反应的是一类方法,这类方法的返回类型是void,两个参数是(int x,int y),因此以后所有具有这样特征的方法都可以用这个委托来代替,现有以下这个方法:

     static void Add(int x, int y){Console.WriteLine("x+y={0}",x+y);}

这个方法,满足委托所定义的这一类方法,但是如何利用委托来调用这个方法呢,首先要将这个方法赋值给这个委托才可以使用,就如普通的类赋值一样,

CalculatorHandler calhandler = new CalculatorHandler(Add)

当然你也可以像给一个字符串赋值一样,这样给委托赋值:

CalculatorHandler calhander = Add;

当要调用这个方法的时候,你可以就像使用方法一样使用委托,

calhander(3,4);

委托也可以绑定多个方法,当调用这个委托时,会调用所有已经绑定了的方法,如现在还有这样的方法:

        static void Multiply(int x, int y){Console.WriteLine("x*y={0}",x*y);}

只需在calhandler基础上多绑定个方法,具体语法:

calhander += Multiply;

这样当调用

calhander(3,4);

会同时调用Add和Multiply这两个方法,你也可以利用“-=”解绑方法:

calhander -= Multiply;

这样再次调用这个委托,则只会调用Add这个方法。

2. 事件

一说到事件总会有发布者(publisher)和订阅者(subscriber),发布者定义了一个事件,订阅者订阅了该事件(指的是当该事件触发时,订阅者做出什么样的反应,即利用相应的函数去处理)。该函数的定义与定义该事件的委托必须配套。代码如下:

public delegate void MessageEventHandler();class Publisher{public event MessageEventHandler MessageEvent;public void DoSomething(){Console.WriteLine("等待消息");Console.WriteLine("首长来啦!!!");OnMessageEvent();}public void OnMessageEvent(){if (MessageEvent != null){MessageEvent();}}}class Subscriber{public Subscriber(Publisher p){p.MessageEvent += Response;}public void Response(){Console.WriteLine("首场,辛苦了");}
}class Program{static void Main(string[] args){Publisher p = new Publisher();Subscriber s = new Subscriber(p);p.DoSomething();Console.ReadKey();}}
}

这就是事件的基本用法,但是事件与委托到底有什么区别呢,从上面的代码可以看出,事件是根据委托来定义的,

public event MessageEventHandler MessageEvent

其实它是利用委托来规定订阅者处理函数的类型(相同的返回类型和参数即为一类),然后方便在发布者自身的类中来触发订阅者的这些函数。

但是为什么要事件呢,要实现这些,我仅用委托也可以实现呀,如下代码:

 public delegate void MessageEventHandler();class Publisher{public MessageEventHandler MessageEvent;//为了方便,委托名与原来的事件名相同。// public event MessageEventHandler MessageEvent;public void DoSomething(){Console.WriteLine("等待消息");Console.WriteLine("首长来啦!!!");OnMessageEvent();}public void OnMessageEvent(){if (MessageEvent != null){MessageEvent();}}}class Subscriber{public Subscriber(Publisher p){p.MessageEvent += Response;}public void Response(){Console.WriteLine("首场,辛苦了");}}class Program{static void Main(string[] args){Publisher p = new Publisher();Subscriber s = new Subscriber(p);p.DoSomething();Console.ReadKey();}
}

这样子也同样可以产生相同的结果。

但是当客户端如下调用呢?

 Publisher p = new Publisher();Subscriber s = new Subscriber(p);p.DoSomething();p.MessageEvent();Console.ReadKey();

客户端是不是能随意让发布者产生事件,因此我们可否将发布者的委托定义为private,因为只有发布者的内部才能触发事件嘛,其他人怎么可以?但是这样订阅者就无法订阅了,那我们是否可以增加绑定和解除的函数来订阅此委托呢?

public delegate void MessageEventHandler();class Publisher{private MessageEventHandler MessageEvent;// public event MessageEventHandler MessageEvent;public void DoSomething(){Console.WriteLine("等待消息");Console.WriteLine("首长来啦!!!");OnMessageEvent();}public void OnMessageEvent(){if (MessageEvent != null){MessageEvent();}}public void Add_MessageEvent(MessageEventHandler m){MessageEvent += m;               }public void Reomove_MessageEvent(MessageEventHandler m){MessageEvent -= m;}}class Subscriber{public Subscriber(Publisher p){//p.MessageEvent += Response;
            p.Add_MessageEvent(Response);}public void Response(){Console.WriteLine("首场,辛苦了");}}class Program{static void Main(string[] args){Publisher p = new Publisher();Subscriber s = new Subscriber(p);p.DoSomething();           Console.ReadKey();}}
}

这样就可以实现与事件一样的功能,因此为了方便微软为我们提供了事件访问器,何为事件访问器?

public delegate void MessageEventHandler();class Publisher{private MessageEventHandler MessageEvent;// public event MessageEventHandler MessageEvent;public event MessageEventHandler TestEvent{add{lock (MessageEvent){MessageEvent += value;}}remove{lock (MessageEvent){MessageEvent -= value;}}}public void DoSomething(){Console.WriteLine("等待消息");Console.WriteLine("首长来啦!!!");OnMessageEvent();}public void OnMessageEvent(){if (MessageEvent != null){MessageEvent();}}}class Subscriber{public Subscriber(Publisher p){p.TestEvent += Response;}public void Response(){Console.WriteLine("首场,辛苦了");}}class Program{static void Main(string[] args){Publisher p = new Publisher();Subscriber s = new Subscriber(p);p.DoSomething();           Console.ReadKey();}
}

以上的代码就是利用事件访问器来让委托绑定订阅者的方法,事件访问器中的add和remove能自动编译为+=和-=。

通过reflector,我们可以看到一个事件是如何定义的:

它是申明一个私有的委托:

private MessageEventHandler MessageEvent;

另外利用两个函数来绑定与解除订阅者的方法。

转载于:https://www.cnblogs.com/Celvin-Xu/p/3562506.html

C#事件与委托的区别相关推荐

  1. c# 事件和委托的区别,使用事件的好处

    网上一些介绍事件 (event) 的文章让人看来觉得事件和委托好像有很大的不同.通常,事件被作为一种特殊的类型或结构来看待.但事实上,事件只是委托的一个修饰符 (modifier),此外编译器增加了一 ...

  2. 说说.net事件和委托。

        一说到.net的事件,也许你会想都说教程满天飞,一个被说烂了的东西还有什么可以说的啊?是啊,的确有很多好文章剖析事件,比如张子阳先生的C# 中的委托和事件 重温Observer模式--热水器· ...

  3. C#中的事件和委托(续)

    引言 如果你看过了 C#中的委托和事件 一文,我想你对委托和事件已经有了一个基本的认识.但那些远不是委托和事件的全部内容,还有很多的地方没有涉及.本文将讨论委托和事件一些更为细节的问题,包括一些大家常 ...

  4. C#事件与委托(详解)

    C#事件与委托详解[精华 多看看] Delegate delegate是C#中的一种类型,它 实际上是一个能够持有对某个方法的引用的类. 与其它的类不同,delegate类能够拥有一个签名(signa ...

  5. C#事件与委托详解【精华 多看看】--转载于https://www.cnblogs.com/sjqq/p/6917497.html

    Delegate delegate是C#中的一种类型,它实际上是一个能够持有对某个方法的引用的类.与其它的类不同,delegate类能够拥有一个签名(signature),并且它"只能持有与 ...

  6. java eventhandler 触发_事件、委托、委托方法的总结(使用EventHandler)

    在C#中,定义事件.委托.委托方法可以使用类库内的EventHandler泛型委托来定义事件.并根据该泛型委托定义实现方法: 同样您也可以自定义委托 来定义事件以及 根据自定义的委托来定义实现事件的方 ...

  7. C#中的委托和事件 (4)---事件和委托的编译代码

    事件和委托的编译代码 这时候,我们不得不注释掉编译错误的行,然后重新进行编译,再借助Reflactor来对 event的声明语句做一探究,看看为什么会发生这样的错误: public event Gre ...

  8. 第十五节:Expression表达式目录树(与委托的区别、自行拼接、总结几类实例间的拷贝)

    一. 基本介绍 回忆: 最早接触到表达式目录树(Expression)可能要追溯到几年前使用EF早期的时候,发现where方法里的参数是Expression<Func<T,bool> ...

  9. 事件与委托的一点概念理解

    事件与委托的一点概念理解 早就接触过delegate和event,但是始终是一知半解,今天刚好有机会就好好研究一下! Delegate 顾名思义就是委托,委托的意思就是麻烦别人帮我干些事情.比如,我要 ...

最新文章

  1. python 开发板-MicroPython:STM32 上 的 Python 开发
  2. rmi反序列化导致rce漏洞修复_JAVA反序列化漏洞解决办法
  3. 数字图像处理之几何变换
  4. P3321 [SDOI2015]序列统计(未解决)
  5. 排序算法(6)----计数排序
  6. C++数据结构04--顺序栈的实现
  7. linux c++开发_Linux/Windows下进行C/C++开发的差异
  8. 【论文复现】Character-level Convolutional Networks for Text Classification
  9. 用这4种策略提高你的Facebook广告浏览量
  10. JS中的 $(function(){ }) 是什么意思
  11. css中relative、absolute和float
  12. 【Chrome扩展程序】解决“只能通过Chrome网上应用商店安装该程序”的方法
  13. Python爬取自然风景图片代码
  14. 如何获取PDF修改权限并编辑文档?
  15. 量子纠缠:从量子物质态到深度学习
  16. 半年巨亏10亿,水滴烧钱枯竭硬伤难愈
  17. winform中实现打开摄像头+识别条形码和二维码
  18. 基于Android的餐馆订餐点餐app
  19. websocket autobahn jar包的用法
  20. 惠普hp431安装教程10.8.2

热门文章

  1. 解决windows10 wireshark无法抓取发出去的包只能抓取接受数据包
  2. 性能测试如何定位瓶颈?偶发超时?看高手如何快速排查问题
  3. 2019年,被高估的AI与数据科学该如何发展?
  4. 框架:servlet和MVC
  5. 行为型模式:策略模式
  6. Redis:redis入门
  7. 安川g7接线端子图_常用变频器接线端子集锦及接线示意图
  8. 荣耀鸿蒙os2.0报名入口,华为鸿蒙系统2.0在哪报名
  9. 【电商福利】双十二优惠福利专场
  10. 2020年,数据中心的绿色技术演进与创新